Closed cirrusone closed 2 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to this area: @eiriktsarpalis See info in area-owners.md if you want to be subscribed.
Author: | cirrusone |
---|---|
Assignees: | - |
Labels: | `area-System.Linq`, `untriaged` |
Milestone: | - |
You're probably gonna have to take this up with Dapper or EF, because as far as I'm aware, there's absolutely no code in CoreFX that performs Expression->SQL translation like that; it all gets delegated to whatever implements the Query Provider.
Unless you have proof that the expression trees themselves are significantly changed and that's what causes EF/Dapper to interpret them differently.
Dapper is only used to setup the test conditions in this example, it's only EF and EFCore being used where the bug occurs,
The expressions are different between .NET framework and .NET5.0
Expression .NET 4.7.2: Not(((item.Rank >= Convert(1)) And (item.Rank <= Convert(2))))
Expression .NET5.0 : Not(((item.Rank >= Convert(1, Nullable`1)) And (item.Rank <= Convert(2, Nullable`1))))
In that case, it would probably make sense to transfer the issue to the EF repo. That's not discounting that it might be a System.Linq issue, but the EF team should need to take a look first.
Expression.And(exBelow, exAbove)
Expression.And generates a bitwise & operator in the tree. What you need is Expression.AndAlso which generates a boolean && operation. EF Core differentiates both operator separately hence you get a different query.
Ah, that's the issue. Using Expression.AndAlso completely solved my problem and it now works as expected. Sorry for wasting your time and thanks for the help.
Description
Assuming database nullable column
[Rank] [int] NULL
, with data1,2,3,NULL,NULL
the following SQL query should return 1 record of value 3 (ie the nulls are not included).In .NET4.7.2, building an expression to represent this query using System.Linq.Expressions and converting to a sql query using
IQueryProvider IQueryable CreateQuery(Expression expression)
works as expected and gives the following sql query and correctly outputs the expected data.
OUTPUT in .NET4.7.2
However on netcore2.2, netcore3.1 and .NET5.0 it gives different expression, query and the results are incorrect and include NULL. The query includes some unwanted casts to BIT which also converts the NULL values.
OUTPUT in .NET5.0:
As the expression is also different I'm assuming this is a problem with System.Linq rather than EntityFrameworkCore? This was initially discovered migrating an ASP.NET MVC project from .NET4.7.2 to .NET5.0. Since it can be awkward to generate testable project I've simplified the problem into a console app which is easier to test (see below). Only requirement is SQL Server/Express required.
Configuration
Complete testable example .NET4.7.2
Complete testable example .NET5.0