[Practice Note] Net Expression表达式树拓展-And/or/orderby/orderthenby

本文介绍了如何在Net中拓展Expression表达式树,着重讲解了如何实现And、Or操作以及Orderby和OrderThenBy的调用方法,为.NET开发中的动态查询提供了帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值