智商反射



我正在玩弄并试图为 IQueryable 制作一个扩展方法,该方法按对象的任意属性对其进行排序。

public static class IQueryableExtender
{
public static IQueryable<TSource> Sort<TSource>(this IQueryable<TSource> query, string orderProperty, string sortDirection = "asc")      
{
    var elementType = query.ElementType;
    var propertyInfo = elementType.GetProperty(orderProperty);
    if (propertyInfo == null)
    {
         throw new ArgumentException(string.Format("{0} is not a property on {1}", orderProperty, elementType.Name));
    }

    switch (sortDirection.ToLower())
    {
       case "asc":
       case "ascending":
           return query.OrderBy(x => propertyInfo.GetValue(x, null));
           break;
       case "desc":
       case "descending":
           return query.OrderByDescending(x => propertyInfo.GetValue(x, null));
           break;
    }
    return query;
}
}

调用该方法时出现此错误。我想这与IQueryable尚未执行和检索任何对象有关。

LINQ to Entities 无法识别 System.Object GetValue(System.Object, System.Object[]) 的方法,并且此方法无法转换为存储表达式。

我可以通过在 IQueryable 上执行 ToList 来解决它,但随后我在扩展方法中检索数据,这不是我想要的。

这能解决吗?

当您

对 IQueryable<> 执行 LINQ 操作时,LINQ to Entities 会尝试在数据库中运行查询。在您的case "asc"中,您执行查询。OrderBy,LINQ to Entities 将其解释为"将其转换为 SQL",并且由于您使用反射调用而失败,它不知道如何转换为 SQL。

你可以做查询。AsEnumerable()。OrderBy(...)。这样做的一个效果是,当 OrderBy 操作开始运行时,查询的其余部分将执行以提供数据。

与其使用这些反射技巧,不如简单地使用 OrderBy 和 OrderByDescending 方法,这些方法旨在获取委托来提取排序值。(items.OrderBy(item => item.Property))。您缺少的是在同一方法中指定升序或降序的能力,但我只想做一对方法,例如:

public static IOrderedQueryable<TSource> OrderByAscDesc<TSource, TKey>(
    this IQueryable<TSource> source,
    Expression<Func<TSource, TKey>> keySelector, bool isAsc
) {
    return (isAsc ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector);
}
public static IOrderedQueryable<TSource> OrderByAscDesc<TSource, TKey>(
    this IQueryable<TSource> source,
    Func<TSource, TKey> keySelector, bool ascDesc
) {
    return (isDesc ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector);
}

相关内容

  • 没有找到相关文章

最新更新