【问题标题】:LinQ - Error when trying to order by child propertyLinQ - 尝试按子属性排序时出错
【发布时间】:2019-12-01 14:38:15
【问题描述】:

我正在尝试使用 LinQ 获取包含另一个子列表的对象列表。 我需要先按父顺序对这个对象进行排序,然后再按子顺序。 这是我的代码:

public async Task<IEnumerable<Menus>> GetMenus(string modulo)
    {
        var result = this.context.Set<Menus>()
            .Include(det => det.MenusSub)
            .Where(e => e.Modulo.Equals(modulo))
            .OrderBy(s => s.Orden).ThenBy(s => s.MenusSub.OrderBy(p => p.Orden));

        return await result.ToListAsync();
    }

问题来自thenBy,因为执行此查询时返回此错误:

"Message": "比较数组中的两个元素失败。", "StackTrace": " 在 System.Collections.Generic.GenericArraySortHelper1.Sort(T[] keys, Int32 index, Int32 length, IComparer1 比较器)\r\n 在 System.Array.Sort[T](T[] 数组,Int32 索引,Int32 长度,IComparer1 comparer)\r\n at System.Linq.EnumerableSorter1。排序(TElement[] 元素,Int32 计数)\r\n 在 System.Linq.OrderedEnumerable1.GetEnumerator()+MoveNext()\r\n at System.Linq.OrderedAsyncEnumerable2.MoveNextCore(CancellationToken cancelToken)\r\n 在 System.Linq.AsyncEnumerable.AsyncIterator1.MoveNext(CancellationToken cancellationToken)\r\n at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.AsyncSelectEnumerable2.AsyncSelectEnumerator.MoveNext (CancellationToken cancelToken)\r\n 在 System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator2.MoveNextCore(CancellationToken cancellationToken)\r\n at System.Linq.AsyncEnumerable.AsyncIterator1.MoveNext(CancellationToken cancelToken)\r\n 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)\r\n at System.Linq.AsyncEnumerable.Aggregate_[TSource,TAccumulate,TResult](IAsyncEnumerable1 源,TAccumulate 种子, Func3 accumulator, Func2 resultSelector, CancellationToken cancelToken)\r\n 在 C:\Users\ericp\Documents\Mis Proyectos\Ohmio WEB\ohmio-web-server\OhmioData 中的 Ohmio.Data.MenusRepository.GetMenus(String modulo) \Repositorios\MenusRepository.cs:42 行\r\n 在 Ohmio.Servicios.MenusSer Vice.GetMenus(String modulo) 在 C:\Users\ericp\Documents\Mis Proyectos\Ohmio WEB\ohmio-web-server\OhmioServicios\MenusService.cs:line 26\r\n 在 Ohmio.Api.Controladores.MenusController。 GetMenus(String modulo) 在 C:\Users\ericp\Documents\Mis Proyectos\Ohmio WEB\ohmio-web-server\OhmioWEBAPINetCore\Controladores\MenusController.cs:line 26\r\n 在 Microsoft.AspNetCore.Mvc.Internal。 ControllerActionInvoker.InvokeActionMethodAsync()\r\n 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()\r\n 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)\r\n 在 Microsoft。 AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n 在 Microsoft.AspNetCore.Mvc .Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()"

如果我删除 thenBy 语句,一切正常。

有什么想法吗?谢谢!

【问题讨论】:

  • 可以试试.OrderBy(s =&gt; s.Orden).ThenBy(s =&gt; s.MenusSub.Select(p =&gt; p.Orden))
  • 感谢 Mohsin,但不,我得到了同样的错误““无法比较数组中的两个元素。”
  • 你怎么能按照s.MenusSub.OrderBy(p =&gt; p.Orden)的结果排序——这不就是IOrderedQueryable&lt;T&gt;的某种形式吗?

标签: linq .net-core


【解决方案1】:

我认为问题在于s.MenusSub.OrderBy(p =&gt; p.Orden) 正在返回一个对象集合。由于您的自定义对象可能没有实现 IComparableIComparable&lt;T&gt; 它会抛出您看到的异常,这是有道理的,因为它不知道如何比较您的 Menus 类型的两个实例。 .Net 中的集合类型也没有实现IComparable 接口。

相反,您需要删除 ThenBy 并在您的 return 语句中使用投影。像这样:

return await result.Select(r =>
    new Menus
    {
        // Assign Menus properties
        MenusSub = r.MenusSub.OrderBy(p => p.Orden)
    }).ToListAsync();

或者您可以将集合加载到内存中,父排序,然后返回结果,子排序:

foreach (var menu in result)
{
    menu.MenusSub = menu.MenusSub.OrderBy(p => p.Orden);
}

【讨论】:

  • 好的,谢谢马特。我只需要将您的指令修改为 menu.MenusSub = menu.MenusSub.OrderBy(p => p.Orden).ToList();。找出使用 .Include 语句的 net core Eager Loading 不支持对子集合属性进行过滤或排序
猜你喜欢
  • 2022-12-09
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多