簡體   English   中英

EF 6過濾子集合

[英]EF 6 filtering child collections

我正在嘗試將舊項目從Linq2Sql遷移到EF6,我遇到了以下問題。

這個項目是多語言的(即所有文本都有超過1個翻譯),我有以下數據庫結構:

數據庫表的示例

獲取所有使用當前語言ID篩選的所有LocalizedContent記錄的ExampleEntity1對象的最佳方法是什么?

我可以使用以下代碼加載所有帶有所有LocalizedContent記錄的ExampleEntity1對象: dc.ExampleEntity1.Include(ee => ee.TextEntry.LocalizedContents);

在Linq2Sql中,我可以使用loadOptions.AssociateWith過濾LocalizedContent記錄,但我找不到任何loadOptions.AssociateWith解決方案。

我看到了類似的舊問題(2 - 3年前發布),我只是想知道EF6是否有解決方案。 這對我來說是一個非常關鍵的功能,因為我在項目中有幾十個實體,我不想為每個選擇查詢創建自定義對象。

我還發現了EntityFramework.DynamicFilters nuget包可以幫助解決我的問題,但我更願意使用“原生”EF6功能。

如果要在查詢中對數據庫執行過濾,那么(從EF6開始)您必須使用Query方法

Query方法提供對實體框架在加載相關實體時將使用的基礎查詢的訪問。 然后,您可以在執行查詢之前使用LINQ將過濾器應用於查詢,方法是調用LINQ擴展方法,例如ToList,Load等。

using (var context = new BloggingContext()) 
{ 
  var blog = context.Blogs.Find(1); 

  // Load the posts with the 'entity-framework' tag related to a given blog 
  context.Entry(blog) 
    .Collection(b => b.Posts) 
    .Query() 
    .Where(p => p.Tags.Contains("entity-framework") 
    .Load(); 

   // Load the posts with the 'entity-framework' tag related to a given blog  
   // using a string to specify the relationship  
   context.Entry(blog) 
     .Collection("Posts") 
     .Query() 
     .Where(p => p.Tags.Contains("entity-framework") 
     .Load(); 
}

但是,明顯的缺點是您必須為每個條目執行此操作,並且每個Load調用都會對數據庫執行查詢。

除非它對你來說是一個很難的要求,否則我會選擇加載所有本地化,只需在內存中過濾即可使用所選語言。 我很確定性能不會成為問題。

請注意,目前無法過濾加載了哪些相關實體。 包含將始終引入所有相關實體。

Msdn參考

var result = dc.ExampleEntity1.Include(ee =>ee.TextEntry.LocalizedContents)
               .Select(x=>new
               {
                  //Try anonymous or a projection to your model.
                  //As this Select is IQuerable Extension it will execute in the data store and only retrieve filtered data.
                  exampleEntity = x,
                  localizedContetnt = x.TextEntry.LocalizedContents.Where(g=>g.Id==YourKey),
               }).FirstOrDefault();   

您可以嘗試匿名投影來過濾包含實體中的內容

實體框架團隊正在努力,你可以在這里投票

類似的答案

由於如何包含作品,未經測試且在性能方面並不完美...我會手動完成,但這里是您可以做的一個示例。

var result = dc.ExampleEntity1
             .Include(x => x.TextEntry)
             .Include(x => x.TextEntry.LocalizedContents)
             .Include(x => x.TextEntry.LocalizedContents.Local)
             .Where(x => x.id == 'ExampleEntity1Key'
                      && x.TextEntity.LocalContent.Local.Id == 'Value'
              )
             .FirstOrDefault();

這將最終得到一個ExampleEntity1的對象,其中所有導航都是eager加載....其中Local匹配id。

你可以得到本地像...

var listLocalsForExampleEnitity = result.TextEntry.LocalizedContents.Local.ToList();

或者只是從他們已經在mem中的地方打電話給他們。

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM