Reputation: 17418
I am aiming to use this signature:
IEnumerable<T> SearchFor(Expression<Func<T, bool>> expression);
and would like to AND these 2 predicates:
Func<Employee, bool> isActiveEmployee = e => e.DateFired == null;
Func<Employee, bool> isNewEmployee = e => e.DateHired >= DateTime.Today.AddDays(-90);
into an expression. How can I achieve this please?
PS:
Basically, I am trying to use this. But the line:
var body = (BinaryExpression) expression.Body;
in method GetDynamicQuery
taken from here throws an exception:
Unable to cast object of type 'System.Linq.Expressions.InstanceMethodCallExpressionN' to type 'System.Linq.Expressions.BinaryExpression'.
Using this approach:
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);
Upvotes: 2
Views: 2997
Reputation: 27871
I am assuming that you need a real expression that can be translated to SQL by the many data access frameworks.
One solution is to use LinqKit like this:
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);
Then you can wrap your IQueryable
using the AsExpandable
method from LinqKit like this:
var query = context.Employees.AsExpandable().Where(combined_expression);
Or, if you don't want to invoke AsExpandable
, you can expand the new expression and then use it like any other expression like this:
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);
UPDATE:
For the second example you provided, you can do this:
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
Upvotes: 3