C#如何动态创建lambda表达式
作者:巔峰白羊 时间:2022-04-18 21:57:16
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);
}
}
来源:https://blog.csdn.net/qq_33961062/article/details/80223101
标签:C#,lambda,表达式
0
投稿
猜你喜欢
C#自定义日志记录
2021-06-11 23:44:47
Druid(新版starter)在SpringBoot下的使用教程
2021-07-03 20:25:18
Android跳转到通讯录获取用户名称和手机号码的实现思路
2023-12-11 16:42:57
C#利用XML创建Excel文档的实现方法
2022-12-21 07:15:53
Java实现为Word每一页设置不同图片水印的效果
2023-01-30 07:10:04
Java调用wsdl接口的两种方法(axis和wsimport)
2023-06-23 14:41:22
浅谈springioc实例化bean的三个方法
2022-05-18 08:37:56
Android BottomNavigationView底部导航效果
2023-09-20 20:11:57
完美解决idea moudle没有蓝色的小方块的问题
2021-05-28 16:09:03
Android之listfragment的使用例子
2021-05-31 02:10:19
java语法糖之jdk迭代的新特性汇总
2022-07-09 10:05:19
java使用正则抓取网页邮箱
2022-12-02 10:30:30
解决Android Studio 3.0 butterknife:7.0.1配置的问题
2021-08-20 09:23:05
Android自定义图片选择器简单版
2022-05-11 02:38:59
基于Spring概念模型:PathMatcher 路径匹配器
2022-08-20 12:52:38
SpringbootJPA分页 PageRequest过时的替代方法
2022-03-10 11:53:13
rsa加密算法使用示例分享
2021-08-03 20:47:29
IntelliJ IDEA引入第三方jar包或查看Java源码的时候报decompiled.class file bytecode version:52.0(java 8)错误的解决办法
2022-11-24 12:50:16
Android使用VideoView出现无法播放此视频问题的解决方法
2023-01-16 18:01:41
Flutter实现顶部导航栏功能
2023-03-10 17:13:48