EF 6过滤子集合

我正在尝试将旧项目从Linq2Sql迁移到EF6,我遇到了以下问题。

这个项目是多语言的(即所有文本都有超过1个翻译),我有以下数据库结构:

DB表的示例

获取所有使用当前语言ID筛选的所有LocalizedContent记录的ExampleEntity1对象的最佳方法是什么?

我可以使用以下代码加载所有带有所有LocalizedContent记录的ExampleEntity1对象: dc.ExampleEntity1.Include(ee => ee.TextEntry.LocalizedContents);

在Linq2Sql中,我可以使用loadOptions.AssociateWith过滤LocalizedContent记录,但我找不到任何loadOptions.AssociateWith解决方案。

我看到了类似的旧问题(发布时间是2 – 3年前),我只是想知道EF6是否有解决方案。 这对我来说是一个非常关键的function,因为我在项目中有几十个实体,我不想为每个选择查询创建自定义对象。

我还发现了EntityFramework.DynamicFilters nuget包可以帮助解决我的问题,但我更愿意使用“原生”EF6function。

如果要在查询中对数据库执行过滤(从EF6开始),则必须使用Query方法 :

Query方法提供对entity framework在加载相关实体时将使用的基础查询的访问。 然后,您可以在执行查询之前使用LINQ将filter应用于查询,方法是调用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(); 

您可以尝试匿名投影来过滤包含实体中的内容

entity framework团队正在研究这个你可以在这里投票

类似的答案

由于如何包含作品,未经测试且在性能方面并不完美…我会手动完成,但这是您可以做的一个示例。

 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中的地方打电话给他们。

希望这可以帮助