c# – 在LINQ中获取动态OrderBy
发布时间:2020-12-16 01:54:24 所属栏目:百科 来源:网络整理
导读:参见英文答案 Dynamically Sorting with LINQ????????????????????????????????????9个 我在ASP.NET MVC 3站点中的很多页面中使用数据表.他们使用服务器端分页,现在我想基于列标题实现排序.数据表附带iSortCol_0,它是单击列的int值. 我不喜欢这种方法,因为查
参见英文答案 >
Dynamically Sorting with LINQ????????????????????????????????????9个
我在ASP.NET MVC 3站点中的很多页面中使用数据表.他们使用服务器端分页,现在我想基于列标题实现排序.数据表附带iSortCol_0,它是单击列的int值. 我不喜欢这种方法,因为查询最终会像: if(iSortCol_0 == 0) { // query // OderBy(x => x.CarName) } 然后对每列重复这一过程(加上每个列的else子句按降序排序).所以我改变了我的方法,现在将列名传递给服务器. 我想出了以下内容: Expression<Func<vw_Car,string>> sortExpression1 = null; Expression<Func<vw_Car,int>> sortExpression2 = null; switch(columnToSort) { case "InvoiceNo": sortExpression1 = x => x.CarNo; break; case "ClientNumber": sortExpression1 = x => x.ForeName; break; case "ClientName": sortExpression1 = x => x.SurName; break; default: sortExpression2 = x => x.Age.Value; break; } // start of query .OrderByDir(sortDirection,sortExpression1,sortExpression2) 现在OrderByDir如下所示: public static IOrderedQueryable<T> OrderByDir<T>(this IQueryable<T> source,string dir,Expression<Func<T,string>> column1,int>> column2) { if (column1 != null) { return dir == "asc" ? source.OrderBy(column1) : source.OrderByDescending(column1); } if (column2 != null) { return dir == "asc" ? source.OrderBy(column2) : source.OrderByDescending(column2); } return null; } 这适用于它对string或int类型的列进行排序.我有另一列DateTime我要排序,所以我需要编写另一个sortExpression3然后将其添加到我的OrderByDir. 但是我真的不喜欢实现 – 我曾尝试编写一个通用的排序表达式,它将一个对象作为第二个参数而不是string,int,Datetime,但是当这个代码到位时,我得到了Unable来强制转换类型’System.DateTime’键入’System.Object’. LINQ to Entities仅支持转换实体数据模型基元类型. 任何一个关于可能更好的方法的想法? 解决方法
此类扩展应符合您的需求:
public static class LinqExtensions { public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source,string property) { return ApplyOrder(source,property,"OrderBy"); } public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source,"OrderByDescending"); } private static IOrderedQueryable<T> ApplyOrder<T>(IQueryable<T> source,string property,string methodName) { var props = property.Split('.'); var type = typeof(T); var arg = Expression.Parameter(type,"x"); Expression expr = arg; foreach (var prop in props) { // use reflection (not ComponentModel) to mirror LINQ var pi = type.GetProperty(prop); expr = Expression.Property(expr,pi); type = pi.PropertyType; } var delegateType = typeof(Func<,>).MakeGenericType(typeof(T),type); var lambda = Expression.Lambda(delegateType,expr,arg); var result = typeof(Queryable).GetMethods().Single( method => method.Name == methodName && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 2 && method.GetParameters().Length == 2) .MakeGenericMethod(typeof(T),type) .Invoke(null,new object[] { source,lambda }); return (IOrderedQueryable<T>)result; } } 调用示例: query.OrderBy("Age.Value"); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |