0

I am trying to dynamically build the query using an expression tree and here is a simple demo code for the problem I am running into. Thanks so much for your help in advance.

Expression<Func<Product, bool>> left = p => p.ID == 1;
Expression<Func<Product, bool>> right = p => p.ID == 2;
BinaryExpression binaryExpression = Expression.OrElse(left.Body, right.Body);

Expression<Func<Product, bool>> filters = Expression.Lambda<Func<Product, bool>>(binaryExpression, left.Parameters);

query.Where(filters);
query.CountAsync();

When the query is compiled, the query expression is shown below.

DbSet<Product>()
.AsNoTracking()
.Where(p => p.ID == 1 || p.ID == 2)
.Count()

Then DBCommand is executed and I run into the following errors. Seems 'p' cannot be identified.

Exception thrown: 'System.InvalidOperationException' in Microsoft.EntityFrameworkCore.Relational.dll
The LINQ expression 'p' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

But if I simplify the filters like below. Both of them work fine without errors.

  1. use left, it would be Expression<Func<Product, bool>> left = p => p.ID == 1. Compiled expression is shown below.
DbSet<Product>()
.Where(p => p.ID == 1)
.AsNoTracking()
  1. or change left to this. Expression<Func<Product, bool>> left = p => p.ID == 1 || p.ID == 2 Case 2 actually has the exact same compiled expression.
DbSet<Product>()
.Where(p => p.ID == 1 || p.ID == 2)
.AsNoTracking()
  • ParameterExpression compared by reference, you have to correct body before reusing. Check this [my answer](https://stackoverflow.com/a/65833766/10646316) – Svyatoslav Danyliv Jun 02 '22 at 08:23

0 Answers0