2017-04-05 21 views
0

我們需要在我們的應用程序中添加一個新的功能,例如對於我們的DbContext在其DbSets上執行的SELECT查詢,例如在調用MyDbContext.Users或MyDbContext.Students等時(用戶和學生從BaseEntity類繼承,包括一個Propery IsActive),我們將能夠攔截它們,檢查實體是否具有這種基本類型BaseEntity,並以某種方式修改查詢,例如添加一個where子句來檢查IsActive是否爲真。我試圖研究一下接口,但是它的方法(包括可能與我相關的方法)攔截在數據庫上執行的各種SELECT語句,而不僅僅是MyDbContext的dbset。
我如何以正確的方式做到這一點?如何在Entity Framework 6.3中使用攔截機制?

感謝,ashilon

回答

1

攔截器,在這種情況下,也有可能不是你想要的。它們攔截所有DbContext的所有查詢,並且只能直接修改SQL。當你想添加一個where子句時,這太危險了,因爲連接可能會把所有東西搞砸。

如果您有一個存儲庫或一些基類,所有查詢都會通過,請在那裏執行。如果你總是在做context.Students.Where(...)那麼你可以做一件偷偷摸摸的事情,但不能完全確定這是否會起作用,但我不明白爲什麼它不行。

在你的DbContext類上,我會將所有DbSet屬性namesd(如Students)更改爲StudentsDbSet。然後,我將添加此屬性來替換它:

public IQueryable<Student> Students 
{ 
    get { return StudentdsDbSet.Where(a => a.IsActive); } 
} 

所有舊代碼現在都會引用此屬性,強制IsActive僅記錄。然後,如果你需要非在職學生,你可以在學生數據庫(WhereDbSet.Where)(...)上學習,並且你很樂意去。

+0

優秀答案丹尼爾!很好的解釋和很好的解決方法。只是一個小問題:是否有一個原因,你返回IQueryable而不是DbSet? StudentsDbSet也需要是IQueryable嗎?非常感謝。 – ashilon

+1

當您執行Where子句時,現在將成爲IQueryable。它不會再返回一個DbSet。我相信,您需要Context上的DbSet屬性,因爲這就是Entity Framework知道如何連接映射的方式。 –