Skip to content
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

Table spitting sample in docs throws "Sequence contains no elements" from SqlExpressionFactory in EF7 #29196

Closed
ajcvickers opened this issue Sep 24, 2022 · 0 comments
Assignees
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. Servicing-approved type-bug
Milestone

Comments

@ajcvickers
Copy link
Contributor

Table spitting sample in docs throws "Sequence contains no elements" from SqlExpressionFactory in EF7.

Looks related to #28247, but for pure table-splitting.

This is a case where the model has a warning:

warn: 9/24/2022 21:30:49.856 RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning[20606] (Microsoft.EntityFrameworkCore.Model.Validation)
      The entity type 'DetailedOrder' is an optional dependent using table sharing without any required non shared property that could be used to identify whether the entity exists. If all nullable properties contain a null value in database then an object instance won't be created in the query. Add a required property to create instances with null values for other properties or mark the incoming navigation as required to always create an instance.

Nevertheless, code was working in 6.0 and should certainly not throw "Sequence contains no elements."

Unhandled exception. System.InvalidOperationException: Sequence contains no elements
   at System.Linq.ThrowHelper.ThrowNoElementsException()
   at System.Linq.Enumerable.Aggregate[TSource](IEnumerable`1 source, Func`3 func)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressionFactory.AddConditions(SelectExpression selectExpression, IEntityType entityType)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressionFactory.Select(IEntityType entityType)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.CreateShapedQueryExpression(IEntityType entityType)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerQueryableMethodTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.First[TSource](IQueryable`1 source, Expression`1 predicate)
   at Program.Main() in C:\local\code\AllTogetherNow\Daily\Daily.cs:line 117
public class DetailedOrder
{
    public int Id { get; set; }
    public OrderStatus? Status { get; set; }
    public string? BillingAddress { get; set; }
    public string? ShippingAddress { get; set; }
    public byte[]? Version { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public OrderStatus? Status { get; set; }
    public DetailedOrder? DetailedOrder { get; set; }
}

public enum OrderStatus
{
    Pending,
    Shipped
}

public class TableSplittingContext : DbContext
{
    public DbSet<Order> Orders
        => Set<Order>();

    public DbSet<DetailedOrder> DetailedOrders
        => Set<DetailedOrder>();

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFTableSplitting;Trusted_Connection=True")
            .LogTo(Console.WriteLine, LogLevel.Information)
            .EnableSensitiveDataLogging();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<DetailedOrder>(
            dob =>
                {
                    dob.ToTable("Orders");
                    dob.Property(o => o.Status).HasColumnName("Status");
                    dob.Property(o => o.Version).IsRowVersion().HasColumnName("Version");
                });

        modelBuilder.Entity<Order>(
            ob =>
                {
                    ob.ToTable("Orders");
                    ob.Property(o => o.Status).HasColumnName("Status");
                    ob.HasOne(o => o.DetailedOrder).WithOne().HasForeignKey<DetailedOrder>(o => o.Id);
                    ob.Property<byte[]>("Version").IsRowVersion().HasColumnName("Version");
                });
            
    }
}

public class Program
{
    public static void Main()
    {
        using (var context = new TableSplittingContext())
        {
            context.Database.EnsureDeleted();
            context.Database.EnsureCreated();

            context.Add(
                new Order
                {
                    Status = OrderStatus.Pending,
                    DetailedOrder = new DetailedOrder
                    {
                        Status = OrderStatus.Pending,
                        ShippingAddress = "221 B Baker St, London",
                        BillingAddress = "11 Wall Street, New York"
                    }
                });

            context.SaveChanges();
        }

        using (var context = new TableSplittingContext())
        {
            var pendingCount = context.Orders.Count(o => o.Status == OrderStatus.Pending);
            Console.WriteLine($"Current number of pending orders: {pendingCount}");
        }

        using (var context = new TableSplittingContext())
        {
            var order = context.DetailedOrders.First(o => o.Status == OrderStatus.Pending);
            Console.WriteLine($"First pending order will ship to: {order.ShippingAddress}");
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. Servicing-approved type-bug
Projects
None yet
Development

No branches or pull requests

2 participants