-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing parentheses when using Expression.Or over bool (instead of OrElse) #30181
Comments
Thanks, I can indeed see this (repro for SQLite below, SQL Server hides this with CASE blocks). Although your code should work (i.e. I agree there's an EF bug), you should be using Expression.OrElse rather than Expression.Or. When doing that, the parentheses are fine. Minimal repro for SQLiteawait using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
Expression<Func<TestEntity, bool>> expression1 = x => x.Name == "name" && x.Value == "value1";
Expression<Func<TestEntity, bool>> expression2 = x => x.Name == "name" && x.Value == "value2";
var param = Expression.Parameter(typeof(TestEntity), "x");
var body = Expression.OrElse(
Expression.Invoke(expression1, param),
Expression.Invoke(expression2, param)
);
var logicSum = Expression.Lambda<Func<TestEntity, bool>>(body, param);
var res = context.TestEntities.Where(logicSum).Where(x => x.Id == 2).FirstOrDefault();
public class BlogContext : DbContext
{
public DbSet<TestEntity> TestEntities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlite("Data Source=/tmp/foo.sqlite")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
public class TestEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
} |
@roji this one is likely still broken - but will add this exact test to the regression suite to make sure |
OK, clearing out the milestone - if it's still broken let's fix it. |
…n.Or over bool (instead of OrElse) Just adding regression test, bug already fixed by roji in the parentheses work. Resolves #30181
Description
When EntityFrameworkCore generates SQL query it misses important brackets, when I use Expression.Lambda.
In my example it can cause situation, when all additional .Where() statements are being ignored.
Code
Generated SQL
Issue with the SQL
As You can see, it's missing brackets, and now, when first of the two predicates is true, it will skip our second .Where clause at all.
Code description
Of course in this case use of this syntax is unnecessary, but it is just simplified example to illustrate the problem. My original issue was caused in code, when I needed to generate predicate based on list of pairs of values. That's the only way to create logic sum for generic Expression<Func<>> I could find. If there is a simpler way, I'm happy to hear it out(although it doesn't change the fact, that here's a bug).
On the contrary
If Expression.Lambda construction is not used, and describe predicates explicitly, this issue doesn't happen.
Code
Generated SQL
Conclusion
That's exactly how the original SQL should look like, when using Expression.Lambda.
Provider and version information
EF Core version: 7.0.2
Database provider: Microsoft.EntityFrameworkCore.PostgreSQL
Target framework: .NET 6.0
Operating system: Windows 10
IDE: Microsoft Visual Studio Professional 2022 Version 17.2.5
The text was updated successfully, but these errors were encountered: