表达式目录树的应用
1.使用表达式目录树实现两个不同类型的属性赋值:
首先,准备两个实体类
/// <summary> /// 实体类 /// </summary> public class People { public int Age { get; set; } public string Name { get; set; } public int Id; } /// <summary> /// 实体类Target /// PeopleDTO /// </summary> public class PeopleCopy { public int Age { get; set; } public string Name { get; set; } public int Id; }
接着写,数据处理类
/// <summary> /// 生成表达式目录树 泛型缓存 /// </summary> /// <typeparam name="TIn"></typeparam> /// <typeparam name="TOut"></typeparam> public class ExpressionGenericMapper<TIn, TOut>//Mapper`2 { private static Func<TIn, TOut> _FUNC = null; static ExpressionGenericMapper() { ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p"); List<MemberBinding> memberBindingList = new List<MemberBinding>(); foreach (var item in typeof(TOut).GetProperties()) { MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } foreach (var item in typeof(TOut).GetFields()) { MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray()); Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression }); _FUNC = lambda.Compile();//拼装是一次性的 } public static TOut Trans(TIn t) { return _FUNC(t); } }
最后,程序中调用该代码处理
Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 1_000_000; i++) { PeopleCopy peopleCopy = ExpressionGenericMapper<People, PeopleCopy>.Trans(people); } watch.Stop(); generic = watch.ElapsedMilliseconds;
2. 使用表达式目录树,拼装sql语句
internal static class SqlOperator { internal static string ToSqlOperator(this ExpressionType type) { switch (type) { case (ExpressionType.AndAlso): case (ExpressionType.And): return "AND"; case (ExpressionType.OrElse): case (ExpressionType.Or): return "OR"; case (ExpressionType.Not): return "NOT"; case (ExpressionType.NotEqual): return "<>"; case ExpressionType.GreaterThan: return ">"; case ExpressionType.GreaterThanOrEqual: return ">="; case ExpressionType.LessThan: return "<"; case ExpressionType.LessThanOrEqual: return "<="; case (ExpressionType.Equal): return "="; default: throw new Exception("不支持该方法"); } } }
public static class ExpressionExtension { public static void BatchDelete<T>(this IQueryable<T> entities, Expression<Func<T, bool>> expr) { ConditionBuilderVisitor visitor = new ConditionBuilderVisitor(); visitor.Visit(expr); string condition = visitor.Condition(); string sql = string.Format("DELETE FROM [{0}] WHERE {1};" , typeof(T).Name//有可能还得根据泛型去获取 , condition); //然后执行sql } }
3, 合并表达式
/// <summary> /// 合并表达式 And Or Not扩展 /// </summary> public static class ExpressionExtend { /// <summary> /// 合并表达式 expr1 AND expr2 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expr1"></param> /// <param name="expr2"></param> /// <returns></returns> public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { //return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, expr2.Body), expr1.Parameters); if (expr1 == null) return expr2; else if (expr2 == null) return expr1; ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); var left = visitor.Replace(expr1.Body); var right = visitor.Replace(expr2.Body); var body = Expression.And(left, right); return Expression.Lambda<Func<T, bool>>(body, newParameter); } /// <summary> /// 合并表达式 expr1 or expr2 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expr1"></param> /// <param name="expr2"></param> /// <returns></returns> public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { if (expr1 == null) return expr2; else if (expr2 == null) return expr1; ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); var left = visitor.Replace(expr1.Body); var right = visitor.Replace(expr2.Body); var body = Expression.Or(left, right); return Expression.Lambda<Func<T, bool>>(body, newParameter); } public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> expr) { if (expr == null) return null; var candidateExpr = expr.Parameters[0]; var body = Expression.Not(expr.Body); return Expression.Lambda<Func<T, bool>>(body, candidateExpr); } }
方法调用
Expression<Func<People, bool>> lambda1 = x => x.Age > 5; Expression<Func<People, bool>> lambda2 = x => x.Id > 5; Expression<Func<People, bool>> lambda3 = lambda1.And(lambda2); Expression<Func<People, bool>> lambda4 = lambda1.Or(lambda2); Expression<Func<People, bool>> lambda5 = lambda1.Not(); Do1(lambda3); Do1(lambda4); Do1(lambda5);
付费内容,请联系本人QQ:1002453261
本文来自博客园,作者:明志德道,转载请注明原文链接:https://www.cnblogs.com/for-easy-fast/p/12408483.html