实体框架订购包括

时间:2013-03-13 06:02:17

标签: c# linq entity-framework entity-framework-5

我正试图让以下内容起作用:

_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)。

8 个答案:

答案 0 :(得分:36)

您似乎无法在查询中对子集合进行排序。 在查询之后排序或在第二个查询中加载子项。

类似的问题和答案here

答案 1 :(得分:12)

扩展方法Include仅仅是DbQuery.Include的包装。在内部,它不会执行表达式,而只是解析它们,即它采用它们的成员表达式并将它们转换为路径作为字符串。该路径用作DbQuery.Include的输入。

之前已要求增强Include的功能,例如通过包含Where子句来允许部分加载的集合。订购可能是另一个变更请求。但正如您所看到的,由于Include的内部工作,整个机制将不得不重新设计以实现此类增强。我没有在当前的road map上看到它,所以可能需要一段时间......

答案 2 :(得分:11)

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

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

以上示例按顺序对父实体进行排序,并按子实体的顺序属性对子实体进行排序。

答案 3 :(得分:1)

这永远不会有效。 EF include试图理解并将所有内容翻译成SQL,但是你想从中得到很多。加载所有实体而不进行排序和.ToList() - 并为IEnumerable编写扩展方法以获得有序结果。

答案 4 :(得分:1)

我使用此代码通过订购包括,使用选择和函数订购集合的代码。 不是最好的,但是如果子集合很小,就可以正常工作

   // 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;
    }

答案 5 :(得分:0)

通常,如果您使用的是一堆包含,那是因为您需要在视图中访问子属性。我需要在视图中访问它时订购子集合。

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

我可能会对多个调查问题进行调查。当我将模型子集合传递给局部视图时,如果我想以部分视图级别以特定顺序呈现问题。

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

答案 6 :(得分:0)

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

在我的情况下,我需要在视图中循环时对它们进行排序,所以我只在其中进行排序

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

答案 7 :(得分:-3)

您不应将IQueryable类型转换为IEnumerable并致电Include,因为Include类型不支持IEnumerable

简而言之,永远不要在ToList

之后调用包含
IQueryable = server side call (SQL)
IEnumerable = client side (loaded in memory)