Efcore: DefaultIfEmpty().Max() InvalidOperationException throws 'Sequence contains no elements.'

Created on 22 Sep 2019  路  10Comments  路  Source: dotnet/efcore

After update to dotnet core 3.0 RC1 running following code

var value = context.Products.Where(t => t.CategoryId == catId).Select(t => t.Version).DefaultIfEmpty().Max();

throws

System.InvalidOperationException: Sequence contains no elements.
   at int lambda_method(Closure, QueryContext, DbDataReader, ResultContext, int[], ResultCoordinator)
   at bool Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor+QueryingEnumerable<T>+Enumerator.MoveNext()
   at TSource System.Linq.Enumerable.Single<TSource>(IEnumerable<TSource> source)
   at TResult Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute<TResult>(Expression query)
   at TResult Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute<TResult>(Expression expression)
   at TSource System.Linq.Queryable.Max<TSource>(IQueryable<TSource> source)
   at ... (my method that run the code)

Steps to reproduce

Create entity that maps to a simple table Product.cs
``` C#
[Table("tmpExtProduct", Schema = "ext")]
public partial class Product
{
public int Version { get; set; }
public int CategoryId { get; set; }
}

with context 
``` C#
        public virtual DbSet<Product> Products { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Product>(entity =>
            {
                entity.HasKey(e => e.Version)
                    .HasName("PK__Product");

                entity.Property(e => e.Version).ValueGeneratedNever();
            });

            OnModelCreatingPartial(modelBuilder);
        }

Minimal repro

Further technical details

EF Core version: 3.0.0-rc1.19456.14
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.0
Operating system: W10 Pro
IDE: Visual Studio 2019 16.3 Preview 4.0

closed-duplicate customer-reported

Most helpful comment

Work-around
C# var valueFail = context.Products.Where(t => t.CategoryId == catId) .GroupBy(e => 1) .Select(t => t.Max(e => e.Version)) .ToList()[0];
Groupby a constant so whole table will be in one group and then apply aggregate operator.

All 10 comments

Currently we always throw for null result in Min/Max/Average. It should consider existence of DefaultIfEmpty or perhaps other scenarios around nullability.

Work-around
C# var valueFail = context.Products.Where(t => t.CategoryId == catId) .GroupBy(e => 1) .Select(t => t.Max(e => e.Version)) .ToList()[0];
Groupby a constant so whole table will be in one group and then apply aggregate operator.

Is your workaround better then what I found?
C# var value = context.Products.Where(t => t.CategoryId == catId) .Select(t => t.Version) .DefaultIfEmpty().ToList().Max();
This at least gives me hope for a simple replace once maybe previously working syntax comes back.

@anddrzejb - The work-around I posted will process everything on server-side. In your case it will get all the versions from server side to compute max when the categoryId you are comparing gives multiple reasons.

May have same root cause as #18955

How's it going now?

My current workaround is:

var maxSn = await Entities
    .Where(x => x.Date == date)
    .OrderByDescending(x => x.Sn)
    .Select(x => x.Sn)
    .FirstOrDefaultAsync();

It would be nice if provide the following API:

var maxSn= await Entities.MaxOrDefaultAsync(x => x.Sn);

Looks like this stuff does not work even in 3.1
Why is the issue closed?..

The issue is still open...

Duplicate of #20589

How's it going now?

My current workaround is:

var maxSn = await Entities
    .Where(x => x.Date == date)
    .OrderByDescending(x => x.Sn)
    .Select(x => x.Sn)
    .FirstOrDefaultAsync();

It would be nice if provide the following API:

var maxSn= await Entities.MaxOrDefaultAsync(x => x.Sn);

This workaround gets similar performance (sorting done by SQL server) in indexed cases, with the benefit of having a much less awkward syntax.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

leak picture leak  路  3Comments

spottedmahn picture spottedmahn  路  3Comments

ghost picture ghost  路  3Comments

miguelhrocha picture miguelhrocha  路  3Comments

julienshepherd picture julienshepherd  路  3Comments