2012-06-29 34 views
0

使用存儲庫模式和ViewModels,如果不希望原始數據庫對象泄漏到存儲庫之外,如何針對數據庫構建查詢?我如何實際創建查詢而不加載內存中的所有數據庫並使用LINQ to Objects?我無法將IQueryable公開給應用程序的其餘部分。存儲庫模式,ViewModel和ORMs

例如,使用EF我有一堆POCO,其中有一些與db字段匹配的屬性,但也有些東西不是直接支持(現在)以及外鍵ID來阻止N + 1並且更容易查詢等等。我不希望它們泄漏到應用程序的其餘部分,我希望應用程序只看到一個正常的對象圖。

public class DbUser 
{ 
    public int Id { get; set; } 
    public string Name { get set; } 

    public int GroupId { get; set; } 
    public DbGroup Group { get; set; } 

    public ICollection<DbComment> { get; set; } 
} 

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get set; } 

    public Group Group { get; set; } 
    public ICollection<Comment> { get; set; } 
} 

這裏的問題是我的存儲庫將在內部使用EF查詢(和單元測試時的內存中的東西)。但是,如何實現IQueryable<User> FindAll()?我不能只是回到dbContext.Users.Select(u => new User(u)),因爲在那種情況下我失去了所有可能的查詢能力;它只會將全部用戶集合加載到內存中,將所有類型轉換爲DbUser中的User,然後在內存集合上構建LINQ查詢 - 這是非常低效的。

我不能在存儲庫中構建查詢。在一些頁面上,我有查詢選擇幾個字段,但也計算其他相關對象的一些複雜的東西,根據結果進行過濾(例如正數評分的計數),但我也需要在應用程序中回來。我可以選擇所有用於獲取複雜內容的對象並將它們返回給應用程序(但不能用作db實體),但這意味着要選擇大量數據。

基本上我怎麼防止數據庫實體的污染與他們的冗餘代碼和黑客的應用程序的其餘部分,同時仍然保持構建查詢庫的能力外面?

+0

特別是我使用的實體框架,其DbContext和DbSet實現存儲庫和工作單元;我應該使用EF實體作爲模型,並在測試過程中模擬上下文並進行設置?這就是我所傾向的。 – CMircea

回答

1

CQRS(命令查詢責任分離)解決了這個問題。你有'真正'的模型,領域模型,所有的業務規則和所有這些,以及一個基本上是一個簡單的poco(它可以被視圖直接使用)的'query-ony'模型,它將被一個專用查詢唯一存儲庫。

存活模型(EF實體)僅用於與db進行「交談」,回購總是返回或處理域/應用程序對象。基本上,您必須將EF實體映射到域的實體(反之亦然)。通過這種方式,您將擁有各自獨立的模型。