5

我正在使用實體框架4.3.1,採用Code First方法。此外,我正在使用LinqKit以使用PredicateBuilder。實體框架代碼相關表的第一個4.3/LINQKit謂詞

如果我有表像這樣:

地點,時區(很多:1)

..和我想有一些像這樣:

Expression<Func<TimeZone, bool>> pred = PredicateBuilder.True<TimeZone>(); 
pred = pred.And(tz => tz.TimeZoneCode == "EST"); 

List<Location> locations = context.Locations 
    .AsExpandable().Where(pred) 
    .Select(loc => loc).ToList(); 

這是不行的,因爲謂詞構建爲接受時區,但Where()方法接收位置。

我可以重寫,像這樣的斷言,但我不想,因爲我想有一個謂語工廠,創建針對特定類型的謂詞(我不想以這種方式來使用導航性能):

Expression<Func<Location, bool>> pred = PredicateBuilder.True<Location>(); 
pred = pred.And(loc => loc.TimeZone.TimeZoneCode == "EST"); 

我可以使用什麼語法(如果有的話)使用第一個示例中構造的謂詞,它需要一個TimeZone,而不是讓它通過導航屬性來獲取位置並漫遊樹(因爲這是較少可重用)。如果有一種方法可以利用EF關於導航屬性的知識,並且能夠將謂詞範圍用於導航屬性的類型,那將會很不錯。

回答

4

經過大約一個星期的努力,我發現你實際上可以做到這一點。步驟如下:

  1. 定義謂詞是你的內在屬性(subPredicate
  2. Invoke的查詢subPredicate從另一個謂詞(predicate)內,對父對象的屬性。
  3. Expand您的predicateWhere子句中使用它時。

下面是你的榜樣修改後的代碼:

var subPredicate = PredicateBuilder.True<TimeZone>(); 
subPredicate = subPredicate.And(tz => tz.TimeZoneCode == "EST"); 

var predicate = PredicateBuilder.True<Location>(); 
predicate = predicate.And(l => subPredicate.Invoke(l.TimeZone)); 

List<Location> locations = context.Locations 
    .AsExpandable().Where(pred.Expand()) 
    .Select(loc => loc).ToList(); 
+0

感謝您的更新!您可以通過LINQ/LINQKit提供EF可以轉換爲SQL的東西來增加對此謂詞是否適用於服務器端的洞察,或者這是否將EF應用於未經過濾的數據集中的內部蠻力? – 2015-01-27 20:25:08

+0

@PittsburghDBA這導致通過EF調用數據庫,轉換爲SQL。 – Grinn 2015-01-27 21:40:40

+0

謝謝你的這個了不起的後續行動!!!!! – 2015-01-28 16:52:26

1

只是爲了更新它:事實證明,這些謂詞的意圖是過濾主要實體。心理概念是:決定你想要返回的實體,並返回它們。 EF顯然不是爲這種兒童實體的深層謂詞應用而設計的。

一個人(我不記得在哪裏)提出了一個偉大的觀點:如果孩子們已經預先加載,你不會期望一個部分加載的集合。因此,例如,具有發票實體是沒有意義的,但只有一半的發票行。

我想實現的更多的是沿着EXISTS()或IN()的方向,在那裏你可以說「給我所有的發票,哪裏有產品類型'螺母'和'螺栓'的發票行。這是可行的,但您可能需要應用LINQ或撰寫自己的對象。 EF開箱即用的目的是爲您提供發票,然後您可以懶懶地或急切地加載發票行,但不能直接從數據庫中將它們用作過濾器。

我看到有一些構造可以完成某些事情,但語法很快就變得非常難以管理。

不要打市政廳。

+0

我在這種情況下是...大量的閱讀和反覆試驗後編碼我也learn't不打系統,否則你會得到複雜和難看的代碼。啊!!! EF和PredicateBuilder適用於主要實體的作品。你最終對嵌套實體做了什麼?我現在處於十字路口,決定下一步該做什麼。 (我意識到自你的答案已經2年了)。 – 2014-10-23 05:10:25

+0

我們放棄了EF,現在使用SQLClient。這些ORM平臺沒有一個能夠在原始性能方面與ADO.Net競爭,不必介意這些謂詞問題。 – 2014-10-24 16:16:55

+0

@ThomasVeil看看這裏概述的殘酷差異:https://web.archive.org/web/20131205132904/ http://ormbattle.net/ – 2014-10-24 16:22:29