Net Expression表达式树拓展
1.Expression-- And Or
public static class ExpressionExt
{
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
{
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.And);
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.Or);
}
public class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary<ParameterExpression, ParameterExpression> map;
public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
{
this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
}
public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression p)
{
ParameterExpression replacement;
if (map.TryGetValue(p, out replacement))
{
p = replacement;
}
return base.VisitParameter(p);
}
}
}
1.Expression-- Orderby/OrderThenBy
public static class QueryableExtensions
{
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);
}
}
And Or 调用
实体模型:
class S_Student
{
string Name ...
int Age ...
float Score ...
}
---------------------------------------------
Expression<Func<S_Student, bool>> expression1 = i => true;
if(条件1)
expression1 =expression1.And(_=>_.Name="张三");
if(条件2)
expression1 =expression1 .And(_=>_.Age>20)
var linq=_dbcontext.S_Student.where(expression1);
Orderby/ThenOrderby调用
KeyValuePair<string, bool> key = new KeyValuePair<string, bool>("实体属性名称", false);
int index=0;
//遍历处理需要依次排序的keyvaluepair
foreach(.......)
{
keyValue[index++] = key;
}
var linq = (from p .......
select new 实体对象
{
adt_CreateTime=p.adt_CreateTime,
Id = p.adt_Id,
Fix = f1.ItemContent.ToLower(),
Item = p.Item,
Type = f2.ItemContent.ToLower(),
Url = p.Url,
LinkText = p.LinkText,
ToolTip = p.ToolTip,
Target = (f3.ItemContent.ToLower() == TargetType.Blank.ToString() ? 0 : 1),
});
linq=linq.Ex_OrderBy(keyValue);