生成Expression<Func<T,TKey>>lambda表达式 然后调用内置方法
var type = typeof(T); var param = Expression.Parameter(type, type.Name); Func<String, dynamic> KeySelectorFunc = _PropertyName => { return Expression.Lambda(Expression.Property(param, _PropertyName), param); }; IOrderedQueryable<T> OrderedQueryable = OrderByPropertyList[0].Value ? Queryable.OrderBy(source, KeySelectorFunc(OrderByPropertyList[0].Key)) : Queryable.OrderByDescending(source, KeySelectorFunc(OrderByPropertyList[0].Key));
或者直接生成所有表达式树
string command = IsOrderByAsc ? "OrderBy" : "OrderByDescending"; var type = typeof(T); var property = type.GetProperty(OrderByPropertyName); var parameter = Expression.Parameter(type, "p"); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderByExpression = Expression.Lambda(propertyAccess, parameter); var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression)); return source.Provider.CreateQuery<T>(resultExpression) as IOrderedQueryable<T>;
完整扩展方法
public static IOrderedQueryable<T> Ex_OrderBy<T>(this IQueryable<T> source, params KeyValuePair<String, Boolean>[] OrderByPropertyList) where T : class { if (OrderByPropertyList.Count() == 1) return source.Ex_OrderBy(OrderByPropertyList[0].Key, OrderByPropertyList[0].Value); if (OrderByPropertyList.Count() > 1) { var type = typeof(T); var param = Expression.Parameter(type, type.Name); Func<String, dynamic> KeySelectorFunc = _PropertyName => { return Expression.Lambda(Expression.Property(param, _PropertyName), param); }; IOrderedQueryable<T> OrderedQueryable = OrderByPropertyList[0].Value ? Queryable.OrderBy(source, KeySelectorFunc(OrderByPropertyList[0].Key)) : Queryable.OrderByDescending(source, KeySelectorFunc(OrderByPropertyList[0].Key)); for (int i = 1; i < OrderByPropertyList.Length; i++) { OrderedQueryable = OrderByPropertyList[i].Value ? Queryable.ThenBy(OrderedQueryable, KeySelectorFunc(OrderByPropertyList[i].Key)) : Queryable.ThenByDescending(OrderedQueryable, KeySelectorFunc(OrderByPropertyList[i].Key)); } return OrderedQueryable; } return null; } public static IOrderedQueryable<T> Ex_OrderBy<T>(this IQueryable<T> source, string OrderByPropertyName, bool IsOrderByAsc = true) where T : class { string command = IsOrderByAsc ? "OrderBy" : "OrderByDescending"; var type = typeof(T); var property = type.GetProperty(OrderByPropertyName); var parameter = Expression.Parameter(type, "p"); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderByExpression = Expression.Lambda(propertyAccess, parameter); var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression)); return source.Provider.CreateQuery<T>(resultExpression) as IOrderedQueryable<T>; // //var param = Expression.Parameter(type, type.Name); //var body = Expression.Property(param, OrderByPropertyName); //dynamic keySelector = Expression.Lambda(body, param); //return IsOrderByDesc ? Queryable.OrderByDescending(source, keySelector) : Queryable.OrderBy(source, keySelector); }
调用方式
//F_Search过后返回一个对象相关字段查询后的IQuerable对象
//然后在对ID,Content,Title进行排序
生成SQL
{SELECT [Extent1].[ID] AS [ID], [Extent1].[Title] AS [Title], [Extent1].[SimpleDescribe] AS [SimpleDescribe], [Extent1].[Content] AS [Content], [Extent1].[ImageList] AS [ImageList], [Extent1].[FaceImageList] AS [FaceImageList], [Extent1].[GroupID] AS [GroupID], [Extent1].[CreateUserID] AS [CreateUserID], [Extent1].[CreateDateTime] AS [CreateDateTime], [Extent1].[IsOpen] AS [IsOpen], [Extent1].[IsShowIndex] AS [IsShowIndex], [Extent1].[ShelveDateTime] AS [ShelveDateTime], [Extent1].[UnShelveDateTime] AS [UnShelveDateTime], [Extent1].[LikeCount] AS [LikeCount], [Extent1].[CommentCount] AS [CommentCount] FROM [dbo].[RX_Article] AS [Extent1] ORDER BY [Extent1].[ID] ASC, [Extent1].[Content] DESC, [Extent1].[Title] ASC}
直到执行查询之前 只是生成sql并没有提前查询数据库 其实原理跟内置方法一样啦
补充 ThenBy 方法
public static IOrderedQueryable<T> Ex_ThenBy<T>(this IOrderedQueryable<T> OrderedQueryable, params KeyValuePair<String, Boolean>[] OrderByPropertyList) where T : class { if (OrderByPropertyList.Count() > 0) { var type = typeof(T); var param = Expression.Parameter(type, type.Name); Func<String, dynamic> KeySelectorFunc = _PropertyName => { return Expression.Lambda(Expression.Property(param, _PropertyName), param); }; for (int i = 0; i < OrderByPropertyList.Length; i++) { OrderedQueryable = OrderByPropertyList[i].Value ? Queryable.ThenBy(OrderedQueryable, KeySelectorFunc(OrderByPropertyList[i].Key)) : Queryable.ThenByDescending(OrderedQueryable, KeySelectorFunc(OrderByPropertyList[i].Key)); } return OrderedQueryable; } return null; } public static IOrderedQueryable<T> Ex_ThenBy<T>(this IOrderedQueryable<T> OrderedQueryable, string OrderByPropertyName, bool IsOrderByAsc = true) where T : class {
var type = typeof(T);
//string command = IsOrderByAsc ? "ThenBy" : "ThenByDescending"; //var property = type.GetProperty(OrderByPropertyName); //var parameter = Expression.Parameter(type, "p"); //var propertyAccess = Expression.MakeMemberAccess(parameter, property); //var orderByExpression = Expression.Lambda(propertyAccess, parameter); //var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression)); //return source.Provider.CreateQuery<T>(resultExpression) as IOrderedQueryable<T>; var param = Expression.Parameter(type, type.Name); var body = Expression.Property(param, OrderByPropertyName); dynamic KeySelector = Expression.Lambda(body, param); return IsOrderByAsc ? Queryable.ThenBy(OrderedQueryable, KeySelector) : Queryable.ThenByDescending(OrderedQueryable, KeySelector); }
var type = typeof(T);
我知道这世界
如露珠般短暂
然而
然而