4

可能重复:
动态 LINQ OrderBy

我正在尝试为 Iqueryable 创建一个动态排序。
所以下面你可以看到我正在关注我在stackoverflow中看到的一些示例。

 var query = dalSession.Query<T>();
            var res = (from x in query orderby Extensions.Sort<T>(query, "FirstName") select x).Skip((paging.CurrentPageRecord)).Take(paging.PageSize);


public static class Extensions
{
    public static IQueryable<T> Sort<T>(this IQueryable<T> query,
                                             string sortField)
    {
        return query.OrderByDescending(s => s.GetType()
                                             .GetProperty(sortField));

    }
} 

这是我得到的例外:

System.Linq.IQueryable 1[Partners.BusinessObjects.Affiliate] Sort[Affiliate](System.Linq.IQueryable1[Partners.BusinessObjects.Affiliate],System.String)

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.NotSupportedException: System.Linq.IQueryable`1[Partners.BusinessObjects.Affiliate] Sort[Affiliate](System.Linq.IQueryable`1[Partners.BusinessObjects.Affiliate], System.String)
4

2 回答 2

3

问题在这里: -

s => s.GetType().GetProperty(sortField)

当您尝试访问 IQueryable 的结果集时,它会被转换为 SQL,并且查询会针对您的数据库运行(而不是在内存中运行)。问题是很明显你的数据库对你的类型一无所知,不能对它们调用任何方法,当然也不能对它们执行任何反射。

您需要构建自己的表达式树,它可以被翻译成 SQL。表达式 API 非常复杂,如果您想真正了解它,您需要阅读大量内容。这是使用表达式 API 为您创建动态查询的一个很好的起点

谢天谢地,您的具体案例相当简单,并且在此处此处此处都有可用的示例,但我确实建议您阅读它以了解发生了什么。如果您只是复制粘贴,那么您或其他人最终将不得不维护它并度过一段非常难过的时光。

于 2012-11-06T13:57:01.863 回答
-1

Iain 是对的,您的 iqueryable 仅在真正需要时才开始提取数据。您可以通过一个简单的技巧 long dummy = query.Count(); 来强制加载。这不是完整的解决方案,您希望避免构建查询树的复杂性,因此如果集合不是非常大,只需将其转换为某种可排序的类型。

于 2012-11-06T14:14:47.950 回答