jav*_*iry 8 entity-framework parent-child ef-code-first entity-framework-4.1
这是这里解释的问题的第二步:EF 4.1代码优先:如何加载相关数据(父子孙子)?.在@Slauma的指导下,我使用这种方法成功检索了数据:
var model = DbContext.SitePages
.Where(p => p.ParentId == null && p.Level == 1)
.OrderBy(p => p.Order) // ordering parent
.ToList();
foreach (var child in model) { // loading children
DbContext.Entry(child)
.Collection(t => t.Children)
.Query()
.OrderBy(t => t.Order) // ordering children
.Load();
foreach (var grand in child.Children) { // loading grandchildren
DbContext.Entry(grand)
.Collection(t => t.Children)
.Query()
.OrderBy(t => t.Order) // ordering grandchildren
.Load();
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这种方法有效,但它会向数据库发送许多查询,而我正在寻找一种方法,只需一个查询即可完成所有操作.在@Slauma的指导下(在上面链接的答案中解释),我已经将查询更改为:
var model2 = DbContext.SitePages
.Where(p => p.ParentId == null && p.Level == 1)
.OrderBy(p => p.Order)
.Include(p => p.Children // Children: how to order theme???
.Select(c => c.Children) // Grandchildren: how to order them???
).ToList();
Run Code Online (Sandbox Code Playgroud)
现在,我如何在选择儿童(和孙子女)时订购(如上面第一个代码示例所示)?
Sla*_*uma 23
不幸的是,eager loading(Include)不支持对加载的子集合进行任何过滤或排序.有三种方法可以实现您的目标:
使用明确排序的加载对数据库进行多次往返.这是您问题中的第一个代码段.请注意,多次往返不一定是坏的,Include嵌套Include 可以导致数据库和客户端之间传输数据的大量增加.
使用eager加载Include或者Include(....Select(....))在加载后对内存中的数据进行排序:
var model2 = DbContext.SitePages
.Where(p => p.ParentId == null && p.Level == 1)
.OrderBy(p => p.Order)
.Include(p => p.Children.Select(c => c.Children))
.ToList();
foreach (var parent in model2)
{
parent.Children = parent.Children.OrderBy(c => c.Order).ToList();
foreach (var child in parent.Children)
child.Children = child.Children.OrderBy(cc => cc.Order).ToList();
}
Run Code Online (Sandbox Code Playgroud)使用投影:
var model2 = DbContext.SitePages
.Where(p => p.ParentId == null && p.Level == 1)
.OrderBy(p => p.Order)
.Select(p => new
{
Parent = p,
Children = p.Children.OrderBy(c => c.Order)
.Select(c => new
{
Child = c,
Children = c.Children.OrderBy(cc => cc.Order)
})
})
.ToList() // don't remove that!
.Select(a => a.Parent)
.ToList();
Run Code Online (Sandbox Code Playgroud)这只是一次往返,如果您不禁用更改跟踪(.AsNoTracking()在此查询中不使用),则可以使用.必须将此投影中的所有对象加载到上下文中(第一个ToList()必要的原因),并且上下文将正确地将导航属性绑定在一起(这是一个称为"关系范围"的功能).
| 归档时间: |
|
| 查看次数: |
8763 次 |
| 最近记录: |