目录
- C#动态创建lambda表达式
- Lambda表达式动态拼接生成工具类
- 总结
C#动态创建lambda表达式
近日在使用了一下EF框架,在做多条件where查询的时候不知道怎么做,网上找了找,一开始用context.Database.SqlQuery<T>方法写sql语句,之后遇到了SqlParamterCollection已在另一定义的问题,找了一下,大概知道什么问题,觉得用EF真的有点不方便,还不如用Dapper开发效率快,之后又在网上搜了搜关键字EF框架多条件Where查询就打开了新世界的大门。
动态创建lambda表达式,我跟着学习了一下写的
代码如下:
//querydata 是Dictionary<string,string> 放着要查询的属性名和相应的值 | |
ParameterExpression pe = Expression.Parameter(typeof(Customer), "customer");//lambda表示式里的参数我这边是单参数 | |
Expression left;//相当于 a=b 的 a | |
Expression right;//相当于a=b 的 b | |
Expression e;//作为最后形成的表达式的载体 | |
//先放一个初始值后面被替换不然循环里不方便用 | |
left = Expression.Property(pe, typeof(Customer).GetProperty("name"));//Customer.name | |
right = Expression.Constant("巅峰白杨");//Constant方法设置属性对应的值 | |
e = Expression.Equal(left, right);//Customer.name=="巅峰白杨" | |
//循环查询条件字典 | |
foreach (var item in querydata) | |
{ | |
if (!item.Value.ToString().Trim().Equals("")) | |
{ | |
left = Expression.Property(pe, typeof(SFC_Package).GetProperty(item.Key)); | |
right = Expression.Constant(item.Value); | |
if (index == 0) | |
{ | |
e = Expression.Equal(left, right); | |
index++; | |
} | |
else | |
{ | |
if (e != null) | |
{ | |
Expression tempe; | |
tempe = Expression.Equal(left, right); | |
e = Expression.And(tempe, e);//加了一个&&连接两个判断 | |
} | |
} | |
} | |
} | |
IQueryable<Customer> queryableData = db.Customer.AsQueryable<Customer>();//将IEnumerable类型转成IQueryable | |
//Where方法的lambda表达式 | |
MethodCallExpression whereCallExpression = Expression.Call( | |
typeof(Queryable), | |
"Where", | |
new Type[] { queryableData.ElementType }, | |
queryableData.Expression, | |
Expression.Lambda<Func<SFC_Package, bool>>(e, new ParameterExpression[] { pe })); | |
//OrderBy方法的lambda表达式 这边写的有点冗余第一次写不太习惯,想想重复了很多 | |
var propertyinfo=typeof(Customer).GetProperty("Name"); | |
Expression body=Expression.Property(pe,propertyinfo); | |
Type nametype=propertyinfo.PropertyType; | |
MethodCallExpression orderByCallExpression = Expression.Call( | |
typeof(Queryable), | |
"OrderBy", | |
new Type[] { queryableData.ElementType, nametype},//其实可以写成queryableData.ElementType.GetProperty("Name").PropertyType | |
whereCallExpression, | |
Expression.Lambda(body, pe)); | |
//使用已创建好的lambda表达式查询数据 ps:IQueryable和IEnumerable可以转换方便处理查询结果 | |
IQueryable<SFC_Package> results = queryableData.Provider.CreateQuery<Customer>(orderByCallExpression); |
网上还看到一种简单的多条件查询的方法,相当于
var data=db.Customer.Where(o=>o.name=="西门吹雪"); | |
data=data.Where(o=>o.sex="男神") |
用循环来多次Where实现多条件查询,感觉可能会造成多次数据库查询,不过用在Linq to Object
上应该挺好的。
最后学习的动态创建lambda表达式地址 点击打开链接
Lambda表达式动态拼接生成工具类
public static class LambdaUtil<T> | |
{ | |
/// <summary> | |
/// lambda表达式:t=>true | |
/// </summary> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> True() | |
{ | |
return t => true; | |
} | |
/// <summary> | |
/// lambda表达式:t=>false | |
/// </summary> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> False() | |
{ | |
return t => false; | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName | |
/// 多用于order排序 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <typeparam name="TKey">返回类型</typeparam> | |
/// <param name="propName">属性名</param> | |
/// <returns></returns> | |
private static Expression<Func<T, TKey>> Order<TKey>(string propName) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个属性 | |
MemberExpression property = Expression.Property(parameter, propName); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, TKey>>(property, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName==propValue | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> Equal(string propName, object propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue); | |
// 创建一个相等比较Expression | |
BinaryExpression binary = Expression.Equal(member, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(binary, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName!=propValue | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> NotEqual(string propName, object propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue); | |
// 创建一个不相等比较Expression | |
BinaryExpression binary = Expression.NotEqual(member, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(binary, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName<propValue | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> LessThan(string propName, object propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue); | |
// 创建一个不相等比较Expression | |
BinaryExpression binary = Expression.LessThan(member, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(binary, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName<=propValue | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> LessThanOrEqual(string propName, object propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue); | |
// 创建一个不相等比较Expression | |
BinaryExpression binary = Expression.LessThanOrEqual(member, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(binary, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName>propValue | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> GreaterThan(string propName, object propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue); | |
// 创建一个不相等比较Expression | |
BinaryExpression binary = Expression.GreaterThan(member, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(binary, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName>=propValue | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> GreaterThanOrEqual(string propName, object propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue); | |
// 创建一个不相等比较Expression | |
BinaryExpression binary = Expression.GreaterThanOrEqual(member, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(binary, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>{t.contains(propvalue1) ||...||t.contains(propvalueN)} | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValues">属性值数组</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> In(string propName, string[] propValues) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // left | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
Expression constant = Expression.Constant(false); | |
// 创建一个方法 | |
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); | |
foreach (string item in propValues) | |
{ | |
// 创建一个带参数方法Expression | |
MethodCallExpression methodCall = Expression.Call(member, method, Expression.Constant(item)); // right | |
// 连接参数方法 | |
constant = Expression.Or(methodCall, constant); | |
} | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(constant, new ParameterExpression[] { parameter }); | |
} | |
/// <summary> | |
/// lambda表达式:t=>{!(t.contains(propvalue1) ||...||t.contains(propvalueN))} | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValues">属性值数组</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> NotIn(string propName, string[] propValues) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
Expression constant = Expression.Constant(false); | |
// 创建一个方法 | |
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); | |
foreach (string item in propValues) | |
{ | |
// 创建一个带参数方法Expression | |
MethodCallExpression methodCall = Expression.Call(member, method, Expression.Constant(item)); // right | |
// 连接参数方法 | |
constant = Expression.Or(methodCall, constant); | |
} | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(Expression.Not(constant), new ParameterExpression[] { parameter }); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName.Contains(propValue) | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> Contains(string propName, string propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue, typeof(string)); | |
// 创建一个方法 | |
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); | |
// 创建一个带参数方法Expression | |
MethodCallExpression methodCall = Expression.Call(member, method, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(methodCall, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName.Contains(propValue) | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> StartWith(string propName, string propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue, typeof(string)); | |
// 创建一个方法 | |
MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); | |
// 创建一个带参数方法Expression | |
MethodCallExpression methodCall = Expression.Call(member, method, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(methodCall, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>t.propName.Contains(propValue) | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> EndsWith(string propName, string propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue, typeof(string)); | |
// 创建一个方法 | |
MethodInfo method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) }); | |
// 创建一个带参数方法Expression | |
MethodCallExpression methodCall = Expression.Call(member, method, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(methodCall, parameter); | |
} | |
/// <summary> | |
/// lambda表达式:!(t=>t.propName.Contains(propValue)) | |
/// 多用于where条件 | |
/// </summary> | |
/// <typeparam name="T">参数类型</typeparam> | |
/// <param name="propName">属性名称</param> | |
/// <param name="propValue">属性值</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> NotContains(string propName, string propValue) | |
{ | |
// 创建节点参数t | |
ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); | |
// 创建一个成员(字段/属性) | |
MemberExpression member = Expression.PropertyOrField(parameter, propName); | |
// 创建一个常数 | |
ConstantExpression constant = Expression.Constant(propValue, typeof(string)); | |
// 创建一个方法 | |
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); | |
// 创建一个带参数方法Expression | |
MethodCallExpression methodCall = Expression.Call(member, method, constant); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(Expression.Not(methodCall), parameter); | |
} | |
/// <summary> | |
/// lambda表达式:t=>{left and right} | |
/// 多用于where条件 | |
/// </summary> | |
/// <param name="left">左侧条件</param> | |
/// <param name="right">右侧条件</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> And(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right) | |
{ | |
// 创建参数表达式 | |
InvocationExpression invocation = Expression.Invoke(right, left.Parameters.Cast<Expression>()); | |
// 创建and运算 | |
BinaryExpression binary = Expression.And(left.Body, invocation); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(binary, left.Parameters); | |
} | |
/// <summary> | |
/// lambda表达式:t=>{left or right} | |
/// 多用于where条件 | |
/// </summary> | |
/// <param name="left">左侧条件</param> | |
/// <param name="right">右侧条件</param> | |
/// <returns></returns> | |
public static Expression<Func<T, bool>> Or(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right) | |
{ | |
// 创建参数表达式 | |
InvocationExpression invocation = Expression.Invoke(right, left.Parameters.Cast<Expression>()); | |
// 创建or运算 | |
BinaryExpression binary = Expression.Or(left.Body, invocation); | |
// 生成lambda表达式 | |
return Expression.Lambda<Func<T, bool>>(binary, left.Parameters); | |
} | |
} |