Skip to content

EF Core 7 - FirstWithoutOrderByAndFilterWarning in simple query with multiple aggregate functions #29782

@raffaele-cappelli

Description

@raffaele-cappelli

In order to perform a simple query with multiple aggregate functions in the select, such as:

select SUM(Value1), SUM(Value2)
from [Table]

I am using "group by (constant value)":

var r = (from x in db.Table
          group x by 1 into g
          select new
          {
            Sum1 = g.Sum(x => x.Value1),
            Sum2 = g.Sum(x => x.Value2),
          }).First();

I noted that in EF7 this produces warning CoreEventId.FirstWithoutOrderByAndFilterWarning ("The query uses the 'First'/'FirstOrDefault' operator without 'OrderBy' and filter operators. ...").

Questions

  • Is this the correct way to perform such queries in EF7, or is there another way that produces better SQL (see below for a complete example with the SQL generated by EF7)?
  • Shouldn't the warning be avoided in these cases (grouping on a constant value), since there will be at most one record in the result?
  • Currently, in order to avoid the warning, is there a better way, other than adding "orderby 1" ?

Example console app

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

using var db = new TestDb();

var qry = from x in db.Table
          group x by 1 into g
          select new
          {
            Sum1 = g.Sum(x => x.Value1),
            Sum2 = g.Sum(x => x.Value2),
          };

Console.WriteLine(qry.ToQueryString());

var result = await qry.FirstAsync();

Console.WriteLine($"{result.Sum1} {result.Sum2}");

class Table
{
  public int Id { get; set; }
  public int Value1 { get; set; }
  public int Value2 { get; set; }
}

class TestDb : DbContext
{
  public DbSet<Table> Table { get; set; }
  protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  {
    optionsBuilder.UseSqlServer("Server=localhost;Database=Test;Trusted_Connection=True;Encrypt=False");
    optionsBuilder.LogTo(Console.WriteLine, LogLevel.Warning);
  }
}

Output of the example app

SELECT COALESCE(SUM([t0].[Value1]), 0) AS [Sum1], COALESCE(SUM([t0].[Value2]), 0) AS [Sum2]
FROM (
    SELECT [t].[Value1], [t].[Value2], 1 AS [Key]
    FROM [Table] AS [t]
) AS [t0]
GROUP BY [t0].[Key]
warn: 06/12/2022 09:00:12.252 CoreEventId.FirstWithoutOrderByAndFilterWarning[10103] (Microsoft.EntityFrameworkCore.Query)
      The query uses the 'First'/'FirstOrDefault' operator without 'OrderBy' and filter operators. This may lead to unpredictable results.
6 60

Provider and version information

EF Core version: 7.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 7.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions