EF 4.1代码优先:如何使用包含和/或select方法命令导航属性?

这是EF4.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(); } } 

它工作,但是,这将发送对数据库的许多查询,我正在寻找一种方法来完成这一切只有一个查询。 在@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(); 

现在,在select儿童(和孙辈)时,我怎样才能下令(如上面的第一个代码)呢?

不幸的是,加载( Include )不支持对已加载的子集合进行过滤或sorting。 有三种select来实现你想要的:

  • 以明确的sorting加载多次往返数据库。 这是你的问题中的第一个代码片段。 请注意,多次往返不一定是错误的, Include和嵌套Include 会导致数据库和客户端之间传输数据的大量增加 。

  • 使用IncludeInclude(....Select(....))进行加载,并在加载之后对数据进行sorting:

     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(); } 
  • 使用投影:

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

如果您.AsNoTracking()用更改跟踪(在此查询中不使用.AsNoTracking() ,则这只是一个往返过程。 此投影中的所有对象都必须加载到上下文中(为什么需要第一个ToList() ),上下文将正确地将导航属性绑定在一起(这是一个名为“Relationship span”的function )。

你有没有尝试跟进?

…select(从ch.property取消selectch的c.children命令)…