-
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
Unexpected query results with UseRelationalNulls and Sum() #34436
Comments
Makes sense; FWIW UseRelationalNulls() is quite a fringe feature that isn't used by many - there are likely to be various other issues with it (and the priority isn't very high). But we should fix these - putting on the backlog. |
For the time being, a work-around is using this function mapping, although I don't like the hack: public static int? SumNullable(int? number) => throw new InvalidOperationException($"{nameof(SumNullable)} cannot be called client side.");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDbFunction(this.GetType().GetRuntimeMethod(nameof(SumNullable), new[] { typeof(int?) }))
.HasTranslation(args =>
new SqlFunctionExpression(
functionName: "SUM ", // Hack: inserted space to prevent EF from reverting to its built-in "SUM" mapping.
arguments: args,
nullable: true,
argumentsPropagateNullability: new[] { true },
type: typeof(int),
typeMapping: null
));
} Usage: db.Tests.Where(t => t.Number == null).Select(t => MyContext.SumNullable(t.Number)) Result: |
The function above can only be used in single 1-dimensional queries. In projections, the generated query is illegal (in SQL Server) because of queried fields that are not in a grouping (I think some other db engines would allow that). I'm not aware of possibilities to replace All in all, I would strongly prefer abandoning this path of making |
@GertArnold I'm not aware of any particular problem with translating Sum() in a way that emulates the .NET behavior; that's generally something we strive to do for all of our translations, and make exceptions here only in very specific cases. The above trouble is specific to UseRelationalNulls() - and we should indeed fix that - but that doesn't seem like it should be a reason to stop coalescing SUM to zero in cases where UseRelationalNulls() isn't being used. |
In .net, see the output of the following statements:
And similar statements in SQL (SQL Server) :
I.e. the database semantics for the
Sum
function is different than .net's.Therefore, when using the
UseRelationalNulls()
option, I'd expectSum
in a LINQ expression to returnnull
when all contributing items arenull
. However, it doesn't. It returns0
.Reproducing code (paste in Linqpad as program, using EF8 NuGet for SQL Server and localdb installed.)
The output of the statements, both with and without
UseRelationalNulls
:So we see that the difference in semantics between .net and the database (row 3 and 4) is not affected by relational nulls settings. For other aggregate functions like
Max
the .net and database semantics are always equal, as said above.The problem is caused by the query translation that always contains
SELECT COALESCE(SUM([t].[Number]), 0)
. I'd expect thisCOALESCE
call to not be added when database null semantics are switched on.EF Core version: 8.0.7
Database provider: Microsoft.EntityFrameworkCore.SqlServer 2019
Target framework: NET 8.0
Operating system: win 11
The text was updated successfully, but these errors were encountered: