Efcore: Case conditions generated for where expression with more than 1 condition

Created on 2 Jul 2020  路  3Comments  路  Source: dotnet/efcore

If i make a query with more than one condition like "Id> 100 and SomeColumn == 10" the SQL generated contains something like
WHERE (CASE WHEN [t].[Id] >0 THEN CAST(1 AS bit)) ELSE CAST(0 AS bit) END AND .....

instead of just
WHERE [t].[Id]>100 AND [t].[SomeColumn] =10

that causes DB to ignore indexes and queries are executed very slow.

But it it is only one condition the resulting SQL is as expected.
What can I do to fix this problem?

EF Core version: 3.1.5
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: e.g. .NET Core 3.1
Operating system: Windows 10
IDE: e.g. Visual Studio 2019 16.3

closed-question customer-reported

Most helpful comment

Expression.Or creates a bitwise OR operation which occurs between 2 values hence case block is introduced to convert the condition to value (that is how SqlServer works).
What you need is Expression.OrElse which creates a logical OR operation and it will generate what you are expecting.

All 3 comments

Please provide a self-contained runnable repro code.

Here it is

```C#
public class A
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}

using (var context = new TestContext())
{
var par = Expression.Parameter(typeof(A), "x");
Expression> ex = Expression.Lambda>(
Expression.Or(
Expression.Equal(
Expression.MakeMemberAccess(par, typeof(A).GetMember("Name").First()),
Expression.Constant("ss")),
Expression.Equal(Expression.MakeMemberAccess(par, typeof(A).GetMember("Name").First()),
Expression.Constant("fff"))), par);
context.As.Where(ex).ToList();
}
context.As.Where(ex).ToList();
```

Probably it's because of lambda or Expression itself. It would be nice form you to suggest anything

Expression.Or creates a bitwise OR operation which occurs between 2 values hence case block is introduced to convert the condition to value (that is how SqlServer works).
What you need is Expression.OrElse which creates a logical OR operation and it will generate what you are expecting.

Was this page helpful?
0 / 5 - 0 ratings