生成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);