Cannot get the dynamic OrderBy to work on my generic list
我不能让动态orderby处理我的常规列表;
1 2 3 4 5 6 7 8 9 10 | var list = CacheObjects.CompetencyAssessments .Select(x => new CompetencyAssessmentLineViewModel(x)) .ToList(); var sortInfo = string.Format("{0} {1}", request.SortingName, request.SortingOrder); var displayList = list.AsQueryable() .OrderBy(sortInfo) .Skip(startIndex) .Take(pageLength); |
我正在使用一个字符串来实现orderby的动态功能。但是代码没有编译;
Error 1 The type arguments for method 'System.Linq.Queryable.OrderBy(System.Linq.IQueryable, System.Linq.Expressions.Expression>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
我做错什么了?
方法的签名是:
1 | public JsonResult GridData(JqGridRequest request) |
而
request.SortingName 是一个带有字段名称的字符串,并且request.SortingOrder 是排序顺序
请参阅:http://tpeczek.com/2011/03/jqgrid-and-aspnet-mvc-strengly-typed.html
我怀疑你把IEnumerable和iqueryable与6年前ScottGuthrie提到的动态Linq库混淆了。这是必须添加到项目中的外部库。它的最新版本是2年前作为Nuget软件包发布的。
这个库有一些限制,所以去年codeplex中出现了另一个system.linq.dynamic项目。
这两个图书馆都不是官方支持的LINQ提供者。如果他们方便的话,你可以使用他们,但是你不应该经常更新他们。
实际上,由于您似乎正在构建一个ASP.NET MVC应用程序,因此在视图或JavaScript中对结果进行排序可能比在服务器端进行排序要好。大多数网格都允许按列排序。
如果您想为分页目的对结果进行排序,一个更好的选择是使用ORM的语言进行排序,例如Entity SQL for Entity Framework或HQL for NHibernate。
问题是动态库在我的项目中被引用了两次。至少我知道如果类似的事情再次发生,应该注意什么。
正如错误消息告诉您的那样,您正在将一个
创建一个字段是很困难的,因为您甚至不知道在编译时要排序的字段的类型。这意味着,一旦生成用于选择属性的适当表达式,就必须使用反射来调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | private static Tuple<Expression, Type> GetSelector<T>(string propertyName) { var parameter = Expression.Parameter(typeof(T)); Expression body = Expression.Property(parameter, propertyName); return Tuple.Create(Expression.Lambda(body, parameter) as Expression , body.Type); } private static IOrderedQueryable<T> OrderBy<T>(IQueryable<T> query, string property, bool ascending) { var selector = GetSelector<T>(property); Type[] argumentTypes = new[] { typeof(T), selector.Item2 }; var methodName = ascending ?"OrderBy" :"OrderByDescending"; var orderByMethod = typeof(Queryable).GetMethods() .First(method => method.Name == methodName && method.GetParameters().Count() == 2) .MakeGenericMethod(argumentTypes); return (IOrderedQueryable<T>) orderByMethod.Invoke(null, new object[] { query, selector.Item1 }); } private static IOrderedQueryable<T> ThenBy<T>(IOrderedQueryable<T> query, string property, bool ascending) { var selector = GetSelector<T>(property); Type[] argumentTypes = new[] { typeof(T), selector.Item2 }; var methodName = ascending ?"ThenBy" :"ThenByDescending"; var orderByMethod = typeof(Queryable).GetMethods() .First(method => method.Name == methodName && method.GetParameters().Count() == 2) .MakeGenericMethod(argumentTypes); return (IOrderedQueryable<T>) orderByMethod.Invoke(null, new object[] { query, selector.Item1 }); } public static IOrderedQueryable<T> OrderBy<T>( this IQueryable<T> query, string property) { return OrderBy<T>(query, property, true); } public static IOrderedQueryable<T> OrderByDescending<T>( this IQueryable<T> query, string property) { return OrderBy<T>(query, property, false); } public static IOrderedQueryable<T> ThenBy<T>( this IOrderedQueryable<T> query, string property) { return ThenBy<T>(query, property, true); } public static IOrderedQueryable<T> ThenByDescending<T>( this IOrderedQueryable<T> query, string property) { return ThenBy<T>(query, property, false); } |
既然我们已经准备好了基于字符串属性进行排序的所有这些内容,那么您基本上可以执行之前想要执行的操作:
1 2 3 4 | var displayList = list.OrderBy(request.SortingName) .ThenBy(request.SortingOrder) .Skip(startIndex) .Take(pageLength); |