-
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
System.ArgumentOutOfRangeException after upgrade to EF Core 2.0 #10045
Comments
Assigning to @smitpatel to investigate:
|
@joshmouch - Can you post exact ordering line? |
In my case, I'm not doing any type of casting. The ordering line looks like this, where the "Id" property is of type Int32:
|
Another difference with #9499 is that in my case, I can use the Include and OrderBy unless I try to Include a Navigation property of a Navigation property.
|
Here is the repro code I used. I am not seeing any exception. Please modify the code so that it can show exception you are seeing. using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFSampleApp
{
public class Program
{
public static void Main(string[] args)
{
using (var db = new MyContext())
{
// Recreate database
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
// Seed database
db.SaveChanges();
}
using (var db = new MyContext())
{
// Run queries
var query = db.Entities
.Include(ar => ar.A)
.Include(ar => ar.B)
.Include(ar => ar.C.D)
.Where(ar => ar.Predicate == 1)
.OrderBy(ar => ar.Id)
.ToList();
}
Console.WriteLine("Program finished.");
}
}
public class MyContext : DbContext
{
// Declare DBSets
public DbSet<Entity> Entities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// Select 1 provider
optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
//.UseSqlite("filename=_modelApp.db")
//.UseInMemoryDatabase(databaseName: "_modelApp")
.EnableSensitiveDataLogging()
.UseLoggerFactory(new LoggerFactory().AddConsole(LogLevel.Trace));
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure model
}
}
public class Entity
{
public int Id { get; set; }
public int Predicate { get; set; }
public List<A> A { get; set; }
public List<B> B { get; set; }
public C C { get; set; }
}
public class A
{
public int Id { get; set; }
}
public class B
{
public int Id { get; set; }
}
public class C
{
public int Id { get; set; }
public int EntityId { get; set; }
public List<D> D { get; set; }
}
public class D
{
public int Id { get; set; }
}
} |
I tried to take your code and change it to as close as possible to my model, and I'm not reproducing it that way, either. Here's my code, below. Is there something else I can try to help you reproduce it? using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace ConsoleApp1
{
public class Program
{
public static void Main(string[] args)
{
using (var db = new MyContext())
{
// Recreate database
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
// Seed database
db.SaveChanges();
}
using (var db = new MyContext())
{
// Run queries
var query = db.Fours
.Include(ar => ar.Fives)
.Include(ar => ar.Two)
.ThenInclude(pf => pf.Threes)
.OrderBy(ar => ar.Id)
.Take(100)
;
var results = query.ToList();
}
Console.WriteLine("Program finished.");
}
}
public class MyContext : DbContext
{
// Declare DBSets
public DbSet<One> Ones { get; set; }
public DbSet<Two> Twos { get; set; }
public DbSet<Three> Threes { get; set; }
public DbSet<Four> Fours { get; set; }
public DbSet<Five> Fives { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// Select 1 provider
optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
//.UseSqlite("filename=_modelApp.db")
//.UseInMemoryDatabase(databaseName: "_modelApp")
.EnableSensitiveDataLogging()
.UseLoggerFactory(new LoggerFactory().AddConsole(LogLevel.Trace));
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure model
modelBuilder.Entity<Five>()
.HasKey(a => new { a.OneId, a.FourId, a.Id });
modelBuilder.Entity<Five>()
.Property(a => a.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Five>()
.HasOne(a => a.One)
.WithMany()
.HasForeignKey(a => a.OneId)
.OnDelete(DeleteBehavior.Restrict)
;
modelBuilder.Entity<Five>()
.HasOne(a => a.ParentFour)
.WithMany(b => b.Fives)
.HasForeignKey(a => new { a.OneId, a.Id })
.OnDelete(DeleteBehavior.Restrict)
;
modelBuilder.Entity<Four>()
.HasKey(a => new { a.OneId, a.Id });
modelBuilder.Entity<Four>()
.Property(a => a.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Four>()
.HasOne(a => a.Two)
.WithMany()
.HasForeignKey(a => new { a.OneId, a.TwoId })
.OnDelete(DeleteBehavior.Cascade)
;
modelBuilder.Entity<Four>()
.HasOne(a => a.One)
.WithMany((Expression<Func<One, IEnumerable<Four>>>)null)
.HasForeignKey(a => a.OneId)
.OnDelete(DeleteBehavior.Restrict)
;
//[DeletedOn], [TwoId], [OneId]
modelBuilder.Entity<Four>()
.HasIndex(ar => new { DeletedOn = ar.Predicate1, ar.OneId, ar.TwoId });
modelBuilder.Entity<Four>()
.HasIndex(ar => new { DeletedOn = ar.Predicate1, ar.OneId, ar.Predicate2, ar.Predicate3 });
modelBuilder.Entity<One>()
.HasKey(a => a.Id);
modelBuilder.Entity<One>()
.Property(a => a.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Two>()
.HasKey(a => new { a.OneId, a.Id });
modelBuilder.Entity<Two>()
.Property(a => a.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Two>()
.HasOne(a => a.One)
.WithMany((Expression<Func<One, IEnumerable<Two>>>)null)
.HasForeignKey(a => a.OneId)
.OnDelete(DeleteBehavior.Restrict)
;
modelBuilder.Entity<Three>()
.HasKey(a => new { a.OneId, a.Id });
modelBuilder.Entity<Three>()
.Property(a => a.Id)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Three>()
.HasOne(a => a.One)
.WithMany((Expression<Func<One, IEnumerable<Three>>>)null)
.HasForeignKey(a => a.OneId)
.OnDelete(DeleteBehavior.Restrict)
;
modelBuilder.Entity<Three>()
.HasOne(a => a.Two)
.WithMany(b => b.Threes)
.HasForeignKey(a => new { a.OneId, a.TwoId })
.OnDelete(DeleteBehavior.Restrict)
;
}
}
public class One
{
public int Id { get; set; }
}
public class Two
{
public int Id { get; set; }
public int OneId { get; set; }
public virtual One One { get; set; }
public ICollection<Three> Threes { get; set; }
}
public class Three
{
public int Id { get; set; }
public int TwoId { get; set; }
public int OneId { get; set; }
public Two Two { get; set; }
public virtual One One { get; set; }
}
public class Four
{
public int Id { get; set; }
public int OneId { get; set; }
public int TwoId { get; set; }
public DateTime? Predicate1 { get; set; }
public bool Predicate2 { get; set; }
public string Predicate3 { get; set; }
public virtual ICollection<Five> Fives { get; set; }
public virtual Two Two { get; set; }
public virtual One One { get; set; }
}
public class Five
{
public int Id { get; set; }
public int FourId { get; set; }
public int OneId { get; set; }
public Four ParentFour { get; set; }
public virtual One One { get; set; }
}
} |
@joshmouch - The root cause of the linked issue which gives same stack-trace is the collection Include & Order By clause together. The Include sends 2 queries. 2nd query is to fetch related data. To correlate data better, both the queries are ordered by Principal key of relationship. If user-specified OrderBy co-incide with it, then it should resolve to same ordering and not add extra. But when that goes wrong then we have 2 orderings in query which would translate to same sql and above exception will be thrown due to mismatch in numbers. |
Got repro. using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFSampleApp
{
public class Program
{
public static void Main(string[] args)
{
using (var db = new MyContext())
{
// Recreate database
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
// Seed database
db.SaveChanges();
}
using (var db = new MyContext())
{
// Run queries
var query = db.Users.Include(u => u.Blog.Posts).OrderBy(e => e.Blog.Id2).ToList();
}
Console.WriteLine("Program finished.");
}
}
public class MyContext : DbContext
{
// Declare DBSets
public DbSet<User> Users { get; set; }
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// Select 1 provider
optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
//.UseSqlite("filename=_modelApp.db")
//.UseInMemoryDatabase(databaseName: "_modelApp")
.EnableSensitiveDataLogging()
.UseLoggerFactory(new LoggerFactory().AddConsole(LogLevel.Trace));
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure model
modelBuilder.Entity<Blog>(b =>
{
b.HasKey(e => new {e.Id1, e.Id2});
b.HasMany(e => e.Posts).WithOne().HasForeignKey(e => new {e.BlogId1, e.BlogId2});
});
}
}
public class User
{
public int Id { get; set; }
public Blog Blog { get; set; }
}
public class Blog
{
public int UserId { get; set; }
public int Id1 { get; set; }
public int Id2 { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int Id { get; set; }
public int BlogId1 { get; set; }
public int BlogId2 { get; set; }
}
} It happens when you do 2nd level collection include and order by key off reference navigation. I also know where the fix will be. |
The issue is navigation rewrite & Include both will try to add ordering on same property |
@smitpatel This is approved; can we get a PR out for it this morning? |
…iler with existing ordering Resolves #10045 The issue: When you have reference.collection include and orderby reference.property, the ordering is expanded by navigation rewrite and it is null-compensated. Whereas the ordering collection include adds missed null-compensation hence they were not matching property causing multiple orderings/projection in QueryModel, which would map to same SqlFragment causing projection count mismatch. The fix is to unique-fy ordering by including null-compensation. Due to new pattern generated by Include, downstream code needs to understand & match more patterns.
Hi, we have a public test feed that you can use to try out the ASP.NET/EF Core 2.0.3 patch! To try out the pre-release patch, please refer to the following guide:
We are looking for feedback on this patch. We'd like to know if you have any issues with this patch by updating your apps and libraries to the latest packages and seeing if it fixes the issues you've had, or if it introduces any new issues. If you have any issues or questions, please reply on this issue to let us know as soon as possible. Thanks, |
Dear, first, excuse my English. I found a similar error. Follow steps to simuate: var query = db.Person I'm using EF 2.0.1 version em System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) |
After upgrading from EF Core 1.1 to 2.0, I started getting an exception when a certain query executes.
The code is along the lines of:
If I comment out the line that adds an OrderBy and a ThenBy to the query, the exception goes away.
Also, if I comment out the Include calls, the exception goes away.
The exception is:
The text was updated successfully, but these errors were encountered: