繁体   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