【问题标题】:Entifyframework core 2.0 filter in ThenIncludeThenInclude 中的 Entifyframework core 2.0 过滤器
【发布时间】:2018-04-21 00:47:32
【问题描述】:
我正在使用 EF core 2.0 并希望过滤子集合。谁能帮助我如何在 EF core 2.0 中做到这一点?
var items = await _context.RiskType
.Include(r => r.Categories)
.ThenInclude(category => category.Alerts)
.ToListAsync();
在上面的代码中我想过滤category.Alerts.where(alert=>alert.caseId==1)
谢谢
【问题讨论】:
标签:
linq-to-entities
entity-framework-core
【解决方案1】:
正如其中一个 cmets 所说,这还不被支持。但是,您可以通过多种方式绕过它。
首先,您可以 .Select() 将所需数据放入匿名或 DTO 对象并使用它。请注意,在下面的示例代码中 .Include() 被 EF Core 忽略,因为存在 .Select() 方法。不过我喜欢用它来清晰。
Parent[] parents = context.Parent
.Include(p => p.Children)
.Select(p => new
{
FilteredChildren = p.Children.Where(/*Filter Func for the children collection*/)
})
.ToArray();
另一种方法是为您需要的某个 Parent 显式加载实体。当您必须为一些父母加载孩子时,这很好,但是如果您有一个大集合并且想要加载所有孩子,请记住显式加载需要访问数据库。在下面的代码示例中,您说要为父条目 .Load() .Collection() ,如果要过滤它,则必须使用 .Query() 以便获取用于获取的查询实体并使用 .Where() 方法应用过滤器。最后你只需要说 .Load() 来加载父实体中的子实体。如果您想对不是集合的导航属性使用显式加载,则必须使用 .Reference() 方法而不是 .Collection()。
Parent parent = context.Parents.Find(/*Key*/);
context.Entry(parent)
.Collection(p => p.Children)
.Query()
.Where(/*Filter Func for the children collection*/)
.Load()
我是 EF 的新手,如果有人有更多建议,我想看看。
【解决方案2】:
使用 EF plus 即可。您可以在任一级别进行过滤。
https://entityframework-plus.net/query-include-filter
var items = ctx.RiskType.IncludeFilter(r=>r.Categories).IncludeFilter(x => x.Categories.Select(p=>p.Alerts.Where(alert=>alert.caseId==1)))
.ToList();
这类似于包含在数据库级别的过滤器(您可以在 db profiler 中看到它)。