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); } } }
下载地址v1:http://pan.baidu.com/s/1jI1I2MU
学习永不止境,技术成就梦想。