EF 6过滤子集合

时间:2015-12-04 01:01:30

标签: c# entity-framework-6

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

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

Example of DB tables

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

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

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

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

我还找到了EntityFramework.DynamicFilters nuget包,可以帮助解决我的问题,但我更愿意使用" native"尽可能使用EF6功能..

3 个答案:

答案 0 :(得分:2)

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

  

Query方法提供对实体框架在加载相关实体时将使用的基础查询的访问。然后,您可以使用LINQ将查询应用于查询,然后再调用LINQ扩展方法(如ToList,Load等)。

assetsfront/img/icon/

然而,明显的缺点是您必须在每个条目中执行此操作,并且每个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(); } 调用都会对数据库执行查询。

除非这对你来说是一个很难的要求,否则我会选择只加载所有本地化,只需在内存中过滤即可使用所选择的语言。我很确定性能不会成为问题。

答案 1 :(得分:1)

  

请注意,目前无法过滤哪些相关内容   实体已加载。包括将永远带来所有相关   实体。

Msdn Reference

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();   

您可以尝试anonymous projection过滤包含的实体

中的内容
  

实体框架小组正在努力解决此问题,您可以投票here

Similar Answer

答案 2 :(得分:-1)

由于包括作品的原因,未经测试且在性能方面并不完美......我会手动完成,但这里是您可以做的一个例子。

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

希望这有帮助