【问题标题】:Entity Framework (.NET Full Framework) Ordering Includes [duplicate]实体框架(.NET 完整框架)排序包括 [重复]
【发布时间】:2013-03-13 06:02:16
【问题描述】:

我正在尝试使以下内容起作用:

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

【问题讨论】:

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


【解决方案1】:

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

类似问答here

【讨论】:

  • 我给了你荣誉,因为你是第一个回答的人,所有三个答案几乎都说同样的话
  • EF 6.0 版仍然如此吗?
【解决方案2】:

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

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

上面的示例按其 Order 对父实体进行排序,并按子实体的 Order 属性对它们的子实体进行排序。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      在我的情况下,我需要在视图中循环时订购它们,所以我只是在那里订购

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

      【讨论】:

        【解决方案5】:

        我使用此代码对包含进行排序,使用选择和函数对集合进行排序。 如果子集合很小,不是最好的,但可以正常工作

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

        【讨论】:

          【解决方案6】:

          这永远行不通。 EF 包含尝试理解并将所有内容转换为 SQL,但您希望从中得到很多。加载所有实体而不进行排序和 .ToList()-ing,并为 IEnumerable 编写扩展方法以获得有序结果。

          【讨论】:

            【解决方案7】:

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

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

            我的调查可能包含多个调查问题。如果我想在将模型子集合传递给局部视图时在局部视图级别以特定顺序呈现问题。

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

            【讨论】:

              【解决方案8】:

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

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

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

              【讨论】:

              • 您的观点是正确的,但与提出的问题无关。我正在尝试在ToList 之前执行Include
              猜你喜欢
              • 1970-01-01
              • 2013-06-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-03-02
              • 1970-01-01
              • 1970-01-01
              • 2010-10-24
              相关资源
              最近更新 更多