在我們的Web.API項目中,我們使用實體框架6.我們有一個DataModel類,它包含DatabaseContext。 DataModel是一個[ThreadStatic]
Singleton。模型類中的EF上下文
像這樣:
public class DataModel
{
[ThreadStatic] private static DataModel _instance;
public static DataModel Instance => _instance ?? (_instance = new DataModel());
public DatabaseContext Context { get; private set; }
private DataModel()
{
Context = NewContext();
}
}
現在,在我們的(部分)模型類之一,我們使用的情況下是這樣的:
public partial class Job
{
public User CreatedByUser
{
get { return DataModel.Instance.Context.Users.FirstOrDefault(d => d.Username == CreatedBy); }
}
}
我們在另一個數據庫中的表對應的用戶搜索。這是有效的,但在我看來,這不是一個美麗的解決方案。特別是如果我們計劃將我們的項目遷移到.NET Core並對數據庫上下文使用依賴注入。
我的問題是,有沒有一種模式,它解決了更優雅的問題?依賴注入在這裏不起作用,因爲實體框架生成模型對象。或者,如果我們將這些代碼從部分類移動到例如一個util類?但是我們怎麼能在那裏注入上下文呢?
實體類中的單例上下文和上下文都是反模式。所以首先嚐試擺脫這些模式,而不用擔心DI。之後你會看到,將代碼轉換爲DI會更容易。 *如何做到這一點,很大程度上取決於你的架構的其他部分,以便對其進行任何明智的說明。 –
這個datamodel駐留在什麼層?它是從API返回的模型還是嘗試在數據庫抽象層?通常我會建議使用存儲庫模式,但這並不適合所有問題。讓模型通過數據庫調用(「活動記錄模式」)填充自己通常會導致比解決問題更多的問題。 – CodeCaster
使用正確的外鍵可以解決問題。作業是通過UserId *上的CreatedBy用戶*關聯的,而不是用戶名(除非用戶名是用戶表中的PK,在這種情況下,您應該重新考慮這一點)。在EF中映射該關係,然後如果實體已連接,則可以使用延遲加載導航到「CreatedByUser」,或者在查詢中使用「包含」子句立即檢索它。您當前的解決方案不是線程安全的,特別是考慮到您有一個具有多個線程的asp.net應用程序(至少1x同時請求)。 – Igor