1.使用表達式目錄樹實現兩個不一樣類型的屬性賦值:sql
首先,準備兩個實體類緩存
/// <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; }
接着寫,數據處理類app
/// <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); } }
最後,程序中調用該代碼處理ui
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語句this
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, 合併表達式spa
/// <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); } }
方法調用pwa
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);