[英]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
调用都会对数据库执行查询。
除非它对你来说是一个很难的要求,否则我会选择加载所有本地化,只需在内存中过滤即可使用所选语言。 我很确定性能不会成为问题。
请注意,目前无法过滤加载了哪些相关实体。 包含将始终引入所有相关实体。
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.