【问题标题】:How to create IQueryable containing OrderBy without Materialization如何在不实现的情况下创建包含 OrderBy 的 IQueryable
【发布时间】:2019-05-08 08:55:14
【问题描述】:

我有以下代码:

public IOrderedQueryable<T> CreateOrderedList<T>(IQueryable<T> items, string orderByprop, string descProperty)
{
    if (!string.IsNullOrEmpty(orderByprop) && !string.IsNullOrEmpty(descProperty))
    {
        return items.OrderedList(orderByprop, descProperty == "desc");                    
    }
    return (IOrderedQueryable<T>)items;
}

public static IOrderedQueryable<T> OrderedList<T>(this IQueryable<T> items, string filterProperty, bool descending = false)
{
    var propertyInfo = typeof(T).GetProperty(filterProperty ?? string.Empty, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
    if (propertyInfo == null)
    {
        throw new Exception("Value not found on T");
    }

    dynamic OrderBy(T o) => propertyInfo.GetValue(o, null);
    return (descending ? (IOrderedQueryable<T>)items.OrderByDescending(OrderBy) : (IOrderedQueryable<T>)items.OrderBy(OrderBy));
}

当我尝试执行此操作时,它给了我以下错误:

无法将 System.Linq.OrderedEnumerable`2[Logic.Models.CRM.Project,System.Object] 类型的对象转换为 System.Linq.IOrderedQueryable`1[Logic.Models.CRM.Project] 类型的对象.

然而,我将更多代码链接到查询(数据过滤),所以我需要对象保持 IQueryable,以便查询稍后具体化。如何实现此功能?

【问题讨论】:

  • 检查this 问题。看来您应该手动构建表达式树

标签: c# iqueryable


【解决方案1】:

我已经解决了我的问题,只需要做一点小改动:

dynamic OrderBy(T o) => propertyInfo.GetValue(o, null);

应该是

Expression<Func<T, dynamic>> orderBy = o => propertyInfo.GetValue(o, null);

因为我使用了委托而不是表达式,这一定迫使 .NET 实现查询而不是扩展表达式

【讨论】:

    【解决方案2】:

    尝试以下方法:

    return descending ? items.Cast<T>.OrderByDescending(OrderBy) 
                      :items.Cast<T>.OrderBy(OrderBy)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      • 2016-06-03
      • 2017-07-22
      • 2019-09-03
      • 2020-04-30
      • 2010-09-10
      • 2011-12-22
      相关资源
      最近更新 更多