將 Linq 中的外鍵設置為 SQL
眾所周知,如果實體已經載入,則不能直接在 Linq to SQL 中設置外鍵 ID。但是,您可以通過實體的外鍵查找實體,然後使用實體關係將該實體設置為外部實體。(為了簡單起見,我在這裡取出了列舉並使用了整數值)。即,如果我有一個載入的約會實體和一個關聯的 AppoinmentStatus 實體,我不能這樣做:-
ExistingAppointment.AppointmentStatusID = 7但我可以這樣做:-
ExistingAppointment.AppointmentStatus = (From appstat In db.AppointmentStatus _ Where appstat.StatusID = 7 _ Select appstat).Single我有這種東西亂扔我的程式碼,我想重構。所以…
我顯然可以在這樣的模組中使用輔助方法:-
Module Helper Public Shared Function GetAppointmentStatus(ByVal AppStatusID As Integer) As AppointmentStatus GetAppointmentStatus = (From appstat In db.AppointmentStatus _ Where appstat.AppointmentStatusID = AppStatus _ Select appstat).Single End Function End Module我什至可以把它變成一個擴展方法,就像這樣。
Imports System.Runtime.CompilerServices Module Helper Extension()> _ Public Shared Function GetAppointmentStatus(ByVal db as DataClassesDataContext, ByVal AppStatusID As Integer) As AppointmentStatus GetAppointmentStatus = (From appstat In db.AppointmentStatus _ Where appstat.AppointmentStatusID = AppStatusID _ Select appstat).Single End Function End Module我也可以把它放在 Linq to SQL 部分類中,就像這樣。
Partial Public Class DataClassesDataContext Public Function GetAppointmentStatus(ByVal AppStatusID As Integer) As AppointmentStatus GetAppointmentStatus = (From appstat In Me.AppointmentStatus _ Where appstat.AppointmentStatusID = AppStatusID _ Select appstat).Single End Function End Class此外,我可以將程式碼放在 Linq to SQL Appointment Entity 部分類中,如下所示:-
Partial Public Class Appointment Public Function GetAppointmentStatus(ByVal db as DataClassesDataContext, ByVal AppStatusID As Integer) As AppointmentStatus GetAppointmentStatus = (From appstat In db.AppointmentStatus _ Where appstat.AppointmentStatusID = AppStatusID _ Select appstat).Single End Function End Class我應該做什麼,為什麼,或者有更好的選擇?
對此有兩種主要的思想流派:
- 將邏輯放入
DataContext(部分類,或者如果您DataContext手動編寫程式碼,則為實際類)。這背後的基本原理是您DataContext已經知道所有不同的實體,因此這不會產生任何額外的耦合,也不會導致類膨脹。當然,缺點是如果你有幾百個這樣的 API 方法(而且你最終可能會),那麼你
DataContext很快就會變成一團泥,裡面塞滿了任何程序員決定投入的每個隨機查詢 API . 你可以嘗試通過將相關函式分離到同一個部分類的不同實例中來清理它DataContext,但這實際上只是一個表面上的改進。 2. 將邏輯放在儲存庫類中,即AppointmentRepository. 這種方法的兩個優點是(a)能夠在儲存庫和 IoC 框架上使用依賴注入,以防您決定更改數據模型,以及(b)您堅持單一責任原則這一事實-將方法放在它所在的位置實際上是有意義的。將這些放在儲存庫中的主要缺點是:(a)它們可能會複製非常相似的邏輯,這些邏輯已經在您
DataContext的儲存過程中;(b) 在交易管理方面,他們有一種讓人頭疼的方式(如果您還使用它們來保存);(c) 當您開始有大量自定義查詢返回針對特定操作或報告的特別定制的 DTO 時,您將面臨兩個糟糕的選擇,要麼為每個 DTO 創建一個儲存庫,要麼創建一個主所有 DTO 或其中一些鬆散相關組的“實用程序”儲存庫。兩者最終都是一個相當糟糕的設計。這些是權衡;只有您可以決定哪個更適合您自己的目的。
我絕對建議不要**使用擴展方法方法,因為擴展方法很難發現(你不能只鍵入方法並讓 Intellisense 獲取相關參考),而且當你有能力時它們也根本沒有必要直接修改或擴展(通過部分)原始類。
我還建議不要擴展
Appointment課程;我們使用 Linq To SQL 之類的工具的原因之一是我們可以處理不需要知道它們來自何處的 POCO實體。出於這個原因,我個人非常反對將實體類與其耦合DataContext——依賴關係應該是單向的。