实体框架(.NET 完整框架)排序包括

我正在努力让下面这些东西发挥作用:

_dbmsParentSections = FactoryTools.Factory.PdfSections
.Include(x => x.Children.OrderBy(y => y.Order).ToList())
.Include(x => x.Hint).Include(x => x.Fields)
.Where(x => x.FormId == FormId && x.Parent == null)
.OrderBy(o => o.Order)
.ToList();

导致例外的部分是:

.Include(x => x.Children.OrderBy(y => y.Order).ToList())

编辑:

经过进一步观察,

_dbmsParentSections.ForEach(x => x.Children = x.Children.OrderBy(y => y.Order).ToList());

为我完成了这项工作(在最初的 Factory呼叫之后,没有 Children.OrderBy)。

64991 次浏览

似乎无法对查询中的子集合进行排序。 要么在查询之后排序,要么在第二个查询中加载子级。

类似的问答 给你

这行不通的。EF include 是尝试理解并将所有内容转换为 SQL,但是您希望从中得到更多。加载所有实体而不进行排序和。ToList ()-ing,并为 IEnumable 编写一个扩展方法以获得一个有序的结果。

扩展方法 Include仅仅是围绕 DbQuery.Include的一个包装器。在内部,它不使用 执行表达式,而只使用 解析表达式,也就是说,它将它们的成员表达式转换为字符串形式的路径。路径用作 DbQuery.Include的输入。

之前已经要求增强 Include的功能,例如通过包含 Where子句允许部分加载集合。订购可能是另一个更改请求。但是正如您所看到的,由于 Include的内部工作原理,必须对整个机制进行重新设计,以实现这些增强。我没有看到它在目前的 路线图所以它可能需要一段时间..。

不应该将 IQueryable类型转换为 IEnumerable并调用 Include,因为 IEnumerable类型不支持 Include

简而言之,绝不要在 ToList之后调用 Include

IQueryable = server side call (SQL)
IEnumerable = client side (loaded in memory)

一般来说,如果您使用一组包含,那是因为您需要访问视图中的子属性。我所做的就是在需要在视图中访问子集合时对其进行排序。

例如,我可能会为主/详细信息表单构建一些 Include 语句。在最初的 EF 查询中排序这个是没有意义的。相反,当您实际访问这些子记录时,为什么不在视图级别对它们进行排序呢?

我可能有一个有多个调查问题的调查。如果我想以特定的顺序展示问题,那么在将模型子集合传递给部分视图时,应该在部分视图级别进行。

@Html.Partial("_ResponsesPartial",Model.SurveyResponses.OrderBy(x =>
x.QuestionId))

我使用这段代码为 include 排序,使用 select 和函数对集合进行排序。 不是最好的,但如果子集合很小,则可以正常工作

   // GET: api/Tareas
[HttpGet]
public IEnumerable<Tarea> GetTareas()
{
var result = _context.Tareas
.Include(p => p.SubTareas)
.Select(p => SortInclude(p));
return result;
}


private Tarea SortInclude(Tarea p)
{
p.SubTareas = (p.SubTareas as HashSet<SubTarea>)?
.OrderBy(s => s.Position)
.ToHashSet<SubTarea>();
return p;
}

根据用例的不同,您可能不需要在单独的查询中加载,或者事后进行排序。

在我的例子中,我需要在视图中循环时订购它们,所以我只在那里订购

@foreach (var subObject in Object.SubObjects.OrderBy(x=>x.Order))

根据 这个文档,从 EF Core 5.0开始,你可以根据包含实体的属性进行排序:

 await context.Parents
.OrderBy(parent => parent.Order)
.Include(parent => parent.Children.OrderBy(child => child.Order))
.ToListAsync();

上面的示例根据它们的 Order 对 Parent 实体进行排序,并根据 Children 实体的 Order 属性对它们的 Children 实体进行排序。