• Expression表达式树 案例


    1,Expression.Invoke

    //运用委托或Lambda表达式
                System.Linq.Expressions.Expression<Func<int, int, bool>> largeSumTest =(num1, num2) => (num1 + num2) > 1000;
                System.Linq.Expressions.InvocationExpression invocationExpression =
                    System.Linq.Expressions.Expression.Invoke(
                        largeSumTest,
                        System.Linq.Expressions.Expression.Constant(539),
                        System.Linq.Expressions.Expression.Constant(281));
                Console.WriteLine(invocationExpression.ToString());//输出:Invoke((num1, num2) => ((num1 + num2) > 1000), 539, 281)
                Console.WriteLine(Expression.Lambda<Func<bool>>(invocationExpression).Compile()());//计算委托 返回false
                Console.ReadKey();

    案例:

    //执行1+2
    var a = Expression.Add(Expression.Constant(1), Expression.Constant(2));
    var lambda = Expression.Lambda<Func<int>>(a).Compile();
                Console.WriteLine(lambda());
    //执行Math.Sin()
    var p = Expression.Parameter(typeof(double), "a");
    //Sin(a)
    var exp = Expression.Call(null, typeof(Math).GetMethod("Sin", BindingFlags.Public | BindingFlags.Static), p);
    //a=>Sin(a)
    var l = Expression.Lambda<Func<double,double>>(exp, p).Compile();
    Console.WriteLine(l(123));
    //执行i => i委托
    Expression<Func<int, int>> ex1 = i => i;
    var paraemter = Expression.Parameter(typeof(int), "a");
    Console.WriteLine(Expression.Lambda<Func<int, int>>(Expression.Invoke(ex1, paraemter), paraemter).Compile()(1));
    //输出:((r.Name == "张三") AndAlso Invoke(r => (r.Sex == "男"), r))
    Expression<Func<Product, bool>> where = r => r.Name == "张三";
    Expression<Func<Product, bool>> where2 = r => r.Sex == "";
    var invoke = Expression.Invoke(where2, where.Parameters);
    Console.WriteLine(invoke);
    var and = Expression.AndAlso(where.Body, invoke);
    Console.WriteLine(and);
    using LinqKit;
    //ef查询
    DbContext db = new DbContext(ConfigurationManager.ConnectionStrings["blogEntities"].ConnectionString);
    Expression<Func<products, bool>> where = r => true;
    Expression<Func<products, bool>> wherename = r => r.Name == "asd";
    where = Expression.Lambda<Func<products, bool>>(Expression.AndAlso(where.Body, Expression.Invoke(wherename,where.Parameters)), where.Parameters);
    var ps = db.Set<products>().AsNoTracking().AsExpandable().Where(where).AsQueryable().ToList();
    foreach (var item in ps)
    {
          Console.WriteLine($"id:{item.Id} qty:{item.Qty} name:{item.Name} aa:{item.AA}");
    }
    //执行Lambda r => r 输出:1
    Expression<Func<int, int>> exr = r => r;
    var invoke = Expression.Invoke(exr, Expression.Constant(1));
    var d = Expression.Lambda(invoke).Compile();
    Console.WriteLine(d.DynamicInvoke());

     一、QueryFilter

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    using System.Reflection;
    
    namespace QueryFilterComplete
    {
        public class QueryFilter
        {
    
            /// <summary>
            /// 查询条件过滤
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="t"></param>
            /// <param name="valNames">需要过滤的字段</param>
            /// <param name="vagueNames">需要模糊查询的字段</param>
            /// <param name="isIgnoreZero">true:忽略0</param>
            /// <returns></returns>
            public static Expression<Func<T, Boolean>> Filter<T,Twhere>(Twhere t, IEnumerable<string> valNames, IEnumerable<string> vagueNames, bool isIgnoreZero = true) where T : class where Twhere:class
            {
                Expression<Func<T, Boolean>> e = r => true;
                foreach (var item in valNames)
                {
                    var result = GetFilterType(item, vagueNames);
                    if (result.Item1 == QFilterType.None) continue;
                    PropertyInfo property = typeof(Twhere).GetProperty(item);
                    var value = property.GetValue(t);
                    if (!Validate(property.PropertyType, value, isIgnoreZero)) continue;
    
                    var rE = Expression.Parameter(typeof(T), "r");
                    var propertyE = Expression.Property(rE, result.Item2);
                    var valueE = Expression.Constant(value);
                    var lambda = Expression.Lambda<Func<T, Boolean>>(ComputeExpression(result.Item1, t, property, propertyE, valueE), rE);
                    var invoke = Expression.Invoke(lambda, e.Parameters);
                    e = Expression.Lambda<Func<T, Boolean>>(Expression.AndAlso(e.Body, invoke), e.Parameters);
                }
                return e;
            }
            private static bool Validate(Type t,object value, bool isIgnoreZero)
            {
                if (value == null) return false;
                if (t.IsValueType)
                {
                    if (t == typeof(DateTime)) return true;
                    if (t == typeof(bool)) return true;
                    if (Convert.ToDouble(value) == 0 && isIgnoreZero) return false;
                }
                return true;
            }
    
            //获取过滤类型
            private static Tuple<QFilterType, string> GetFilterType(string valName, IEnumerable<string> vagueNames)
            {
                QFilterType type = QFilterType.None;
                string propertyName = "";
                if (string.IsNullOrEmpty(valName)) {
                    return Tuple.Create(type, propertyName);
                }
                type = QFilterType.Equal;
                propertyName = valName;
                if (valName.EndsWith("_ge"))
                {
                    type = QFilterType.ge;
                    propertyName = valName.TrimEnd('_', 'g', 'e');
                }
                if (valName.EndsWith("_gt"))
                {
                    type = QFilterType.gt;
                    propertyName = valName.TrimEnd('_', 'g', 't');
                }
                if (valName.EndsWith("_le"))
                {
                    type = QFilterType.le;
                    propertyName = valName.TrimEnd('_', 'l', 'e');
                }
                if (valName.EndsWith("_lt"))
                {
                    type = QFilterType.lt;
                    propertyName = valName.TrimEnd('_', 'l', 't');
                }
                if (valName.EndsWith("_ne"))
                {
                    type = QFilterType.ne;
                    propertyName = valName.TrimEnd('_', 'n', 'e');
                }
                if (valName.EndsWith("_csv"))
                {
                    type = QFilterType.csv;
                    propertyName = valName.TrimEnd('_', 'c', 's', 'v');
                }
                if (vagueNames!=null&&vagueNames.Contains(valName))
                {
                    type = QFilterType.VaguesEqual;
                    propertyName = valName;
                }
                return Tuple.Create(type, propertyName);
            }
            private static Expression ComputeExpression<T>(QFilterType type,T t, PropertyInfo pInfo, Expression propertyE, Expression valueE)
            {
                if (type == QFilterType.Equal)
                {
                    return Expression.Equal(propertyE, valueE);
                }
                if (type == QFilterType.VaguesEqual)
                {
                    //Console.WriteLine(Expression.Call(typeof(Program), "VaguesEqual", null, p, value));
                    return Expression.Call(typeof(QueryFilter), "VaguesEqual", null, propertyE, valueE);
                }
                if (type == QFilterType.ge)
                {
                    return Expression.GreaterThanOrEqual(propertyE, valueE);
                }
                if (type == QFilterType.gt)
                {
                    return Expression.GreaterThan(propertyE, valueE);
                }
                if (type == QFilterType.le)
                {
                    return Expression.LessThanOrEqual(propertyE, valueE);
                }
                if (type == QFilterType.lt)
                {
                    return Expression.LessThan(propertyE, valueE);
                }
                if (type == QFilterType.ne)
                {
                    return Expression.NotEqual(propertyE, valueE);
                }
                if (type == QFilterType.csv)
                {
                    if (pInfo.PropertyType.GetGenericTypeDefinition()==typeof(IEnumerable<>) || pInfo.PropertyType.IsSubclassOf(typeof(IEnumerable<>)))
                    {
                        return Expression.Call(typeof(QueryFilter), "VaguesEqual", new Type[] { pInfo.PropertyType.GenericTypeArguments[0] },Expression.Constant(pInfo.GetValue(t)), propertyE);
                    }
                }
                return null;
            }
    
            private static bool VaguesEqual<T>(IEnumerable<T> t, T value)
            {
                return t.Contains(value);
            }
            //模糊匹配
            private static bool VaguesEqual(string t, string value)
            {
                return t.Contains(value);
            }
    
        }
    }
    View Code

    下载地址v1:http://pan.baidu.com/s/1jI1I2MU

    学习永不止境,技术成就梦想。
  • 相关阅读:
    AT2364 Colorful Balls
    SP5973 SELTEAM
    codeforces469B
    校内题目T2691 桶哥的问题——送桶
    关于一种6的倍数判定素数的方法
    P1903 奖学金题解
    说说关于洛谷P4779迪杰斯特拉的堆优化
    清北学堂北京大学文宏宇神仙讲课day7
    CF961F k-substrings
    CF985F Isomorphic Strings
  • 原文地址:https://www.cnblogs.com/zd1994/p/6678367.html
Copyright © 2020-2023  润新知