我试图将旧项目从Linq2Sql迁移到EF6,我遇到了以下问题。
这个项目是多语言的(即所有文本都有超过1个翻译),我有以下数据库结构:
使用当前语言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功能..
答案 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)
请注意,目前无法过滤哪些相关内容 实体已加载。包括将永远带来所有相关 实体。
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
答案 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中的地方打电话。
希望这有帮助