2013-02-14 67 views
0

我們有一個多層應用程序,其中所有的存儲庫都基於(本土生成的)GenericRepository基類(其中T是模型中的實體),它公開了諸如GetContext(),GetObjectSet()和等等。我們允許從它繼承的存儲庫訪問上下文,因爲他們需要調用Include(),因爲我們通過WCF服務傳遞數據,因此需要加載所有相關實體。從數據庫加載數據時,我可以攔截Entity Framework嗎?

我們所有的實體都實現了一個具有Active bool屬性的接口,我們想要做的是截獲查詢的執行並過濾Active屬性,以便任何查詢只返回設置了該屬性的實體爲真。

可以這樣做嗎?在建立在EF上的Lightswitch中,可以捕獲的事件在查詢執行的深處被正確地啓動,並允許您執行此類過濾。我無法在EF本身找到任何允許這一點的東西。

任何任何想法?謝謝

回答

1

在EF 5,IncludeIQueryable擴展方法,這樣你就可以做到這一點:

var query = dbSet.Where(o => o.IsActive).Include(...) 

這意味着,你不必從通用存儲庫返回一個DbSet<T> - 它應該是確定返回IQueryable<T>。您的建議

partial class GenericRepository<T> 
{ 
    public IQueryable<T> Query(bool includeInactive = false) 
    { 
    return ctx.Set<T>().Where(o => includeInactive || o.IsActive); 
    } 
} 
+0

嗨尼古拉斯,並感謝您的答覆。我不知道有關EF5。我還沒有深入到足以說明這一點,但看起來這可能甚至出現在v4.x版本的某些版本中。無論如何,除了解決一些導致自我跟蹤實體的問題之外,這看起來像是答案。再次感謝。 – 2013-02-17 14:01:29

+0

@AvrohomYisroel很高興我能幫忙:) – 2013-02-17 16:02:05

1

我能想到這樣做的最好方法是讓您的存儲庫方法採用表達式(即Expression<Func<T, bool>> predicate)。這樣,您可以在實際存儲庫本身中執行所有查詢(因此不允許客戶端代碼以任何方式訪問數據層邏輯),您可以在從存儲庫方法返回之前添加Where,直到只抓取那些這是活動的。

這種風格,我用的一個例子是:

public IQueryable<T> Grab(Expression<Func<T, bool>> predicate) 
    { 
    return DbSet.Where(predicate); 
    } 

哪裏DbSet是你想查詢的實際表。通過這種方式,您可以將.Where(x => x.Active)添加到它的末尾,讓它不會針對數據庫執行(謝謝,延遲執行!),但仍然可以獲得您正在查找的確切記錄。

+0

感謝:

如果這符合您的要求,您可以添加一個Where子句的通用存儲庫的方法。不幸的是,這是一個非常成熟的項目,重構倉庫代碼不是一種選擇,其中有很多。這就是爲什麼我們希望在通用存儲庫中這樣做,因爲這樣我們可以更改一個文件,而所有其他文件都會看到更改。如果我們有一個重大改寫的奢侈品,我們會做很多不同的事情!不管怎麼說,還是要謝謝你。 – 2013-02-14 18:18:26

相關問題