0

我正在嘗試構建允許查詢域類的通用存儲庫。針對域類的查詢應針對實體解析

我的倉庫界面看起來如下:

public interface IRepository<T> 
{ 
    T Get(int id); 
    IQueryable<T> Query(); 
    void Add(T model); 
    void Remove(T model); 
} 

假設我有一個UserEntity實體框架類和User域類,我想查詢對UserUserEntity不應該暴露給其他服務,因爲它應該在Entity Framework層內部。

userRepository.Query().Single(user => user.UserName == "Toni")這樣的查詢應返回User域類。但是在內部它應該查詢從我的實體框架返回的IDbSet<UserEntity>。表達式樹(包含Single查詢操作)應附加到針對IDbSet<UserEntity>的查詢中。在查詢IDbSet<UserEntity>後,我想將UserEntity轉換爲User域類。這可能嗎?

我記得要爲我的User類實施一個IQueryable實現,該類對內部查詢UserEntity

public class MappedEntityQuery<TModel, TEntity> : IQueryable<TModel> 
{ 
} 
+0

'UserEntity'(POCO)應該是你的域名類。你所要做的可以被定義爲在ORM之上構建ORM。 –

+0

問題是實體框架要求所有實體都駐留在同一個項目中。我試圖通過爲每個模塊創建項目來模塊化我的ASP.NET MVC應用程序。因此,我希望模塊的域類能夠駐留在單個項目中,這對於EF來說是不可能的。 – Toni

+0

爲什麼不可能? –

回答

1

代碼首先要求公約都IDbSet屬性來訪問表是在的DbContext

這是不正確的。如果您向模型構建器中的實體提供映射,則不需要在上下文中聲明任何集合。在你的情況下,你應該通過EntityTypeConfiguration<T>ComplexTypeConfiguration<T>派生類聲明映射。您可以通過在上下文中調用Set<T>()來創建映射實體類型的任何DbSet實例。

然而,對於這個項目我使用一個數據庫優先的做法,這也不允許加載使用來自不同項目的實體的DbContext組成,因爲你必須在一個單一的元數據文件來指定數據庫的元數據(這將被嵌入)。

這是真的只有部分。 EDMX元數據必須位於主項目中嵌入的單個文件中,但如果您使用自己生成的而不是自己生成的實體類,則不需要這樣做。所以你提出的方法應該可行。

但是,如果你真的想實現模塊化,你不應該使用EDMX。如果您決定在將來添加或更改任何模塊,則需要更改中央項目,但這會影響所有其他模塊 - 它打破了模塊化的想法,不是嗎?

+0

感謝您的深入解釋!我認爲Model First和Database First都需要一個數據庫,並且Code First不能與現有的數據庫一起使用。因此我認爲我不能使用'EntityTypeConfiguration '和'ComplexTypeConfiguration '。戰略如何調用(所以我可以更深入地使用Google) – Toni

+0

我開始使用駐留在單個數據層項目中的單個* .edmx文件實現Database First模型。然後我開始把實體類放在其他項目中。我瞭解到,您必須確保名稱空間和類型名稱必須匹配,並且所有屬性(包括導航屬性)必須存在於實體類中。否則就會拋出一個異常,無法找到實體(這導致我認爲這種違規行爲不會起作用)。 – Toni

+0

不幸的是,這種方法稱爲代碼優先,但不是創建一個新的數據庫,而是使用現有的數據庫(您只需要通過將初始化設置爲空來關閉生成功能)。 –