把谓词组合成表达式

本文关键字:表达式 组合 谓词 | 更新日期: 2023-09-27 18:20:02

我打算使用这个签名:

IEnumerable<T> SearchFor(Expression<Func<T, bool>> expression);

并且想要对这两个谓词进行and运算:

Func<Employee, bool> isActiveEmployee = e => e.DateFired == null;
Func<Employee, bool> isNewEmployee = e => e.DateHired >= DateTime.Today.AddDays(-90);

转化为表达式。请问我怎样才能做到这一点?

PS:

基本上,我正在尝试使用这个。但这条线:

var body = (BinaryExpression) expression.Body;

在从这里获取的方法GetDynamicQuery中抛出异常:

无法将"System.Linq.Expressions.InstanceMethodCallExpressionN"类型的对象强制转换为"System.Linq.Expressions.BinaryExpression"类型。

使用这种方法:

Expression<Func<Employee, bool>> isActiveEmployee = e => e.DateFired == null;
Expression<Func<Employee, bool>> isNewEmployee = e => e.DateHired >= DateTime.Today.AddDays(-90);
Expression<Func<Employee, bool>> combined_expression = e => isActiveEmployee.Invoke(e) && isNewEmployee.Invoke(e);

把谓词组合成表达式

我假设您需要一个可以被许多数据访问框架转换为SQL的真实表达式。

一种解决方案是像这样使用LinqKit:

Expression<Func<Employee, bool>> isActiveEmployee = e => e.DateFired == null;
Expression<Func<Employee, bool>> isNewEmployee = e => e.DateHired >= DateTime.Today.AddDays(-90);
Expression<Func<Employee, bool>> combined_expression = e => isActiveEmployee.Invoke(e) && isNewEmployee.Invoke(e);

然后,您可以使用LinqKit中的AsExpandable方法包装您的IQueryable,如下所示:

var query = context.Employees.AsExpandable().Where(combined_expression);

或者,如果您不想调用AsExpandable,您可以展开新的表达式,然后像以下任何其他表达式一样使用它:

Expression<Func<Employee, bool>> combined_expression = e => isActiveEmployee.Invoke(e) && isNewEmployee.Invoke(e);
combined_expression = combined_expression.Expand();
var query = context.Employees.Where(combined_expression);

更新:

对于您提供的第二个示例,您可以这样做:

Expression<Func<Employee, bool>> expression1 = e => e.Guid == new Guid("28D3BCFB-9472-4141-BD88-BE5E7E1230F0");
Expression<Func<Employee, bool>> expression2 = e => e.Guid == new Guid("0F0DBA45-F842-4E46-9ED4-F50B5BCF0509");
Expression<Func<Employee, bool>> combined_expression = e => expression1.Invoke(e) || expression2.Invoke(e);
combined_expression = combined_expression.Expand();
// use combined_expression