-
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
Expression of type 'System.Object' cannot be used for parameter of type 'Microsoft.EntityFrameworkCore.Metadata.IEntityType' #9551
Comments
Repro 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.AddRange(
new Blog
{
Posts = new List<Post>
{
new Post(),
new Post(),
new Post()
}
},
new Blog
{
Posts = new List<Post>
{
new Post(),
new Post(),
new Post()
}
}
);
db.SaveChanges();
}
using (var db = new MyContext())
{
// Run queries
var query = db.Set<Post>()
.Include(p => p.Blog)
.GroupBy(p => EF.Property<int?>(p, "BlogId"))
.Select(g => g.OrderBy(e => e.Id).FirstOrDefault()).ToList();
}
Console.WriteLine("Program finished.");
}
}
public class MyContext : DbContext
{
// Declare DBSets
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());
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure model
}
}
public class Blog
{
public int Id { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int Id { get; set; }
public Blog Blog { get; set; }
} |
Include with GroupBy and Select with single result operator. |
@maumar this bug! |
Just when I thought I might have gotten through with migrating to 2.0.. .more Entity Framework regressions. Back to 1.x I go I suppose. |
@twilliamsgsnetx i'm also disappointed that I have had to retest my entire code base because this has affected a few places but I wouldn't be so hasty as to roll back, especially if you've already done the hard part of migrating. I would suggest simply using ef to do the selects but for any grouping operations do that after you have called toList |
Problem is that when we apply Include on the selector, need to special case group by (apply include on element selector, rather than on qsre directly) - this logic is located in However, for more complex scenarios the logic is not correct, as we only look at the top level query model and top level expression type to determine whether we are dealing with GroupBy query. In the problematic case group by is "hidden" in a subquery. Workaround: add ToList() after GroupBy call, there is no perf hit, since (in 2.0) everything after Groupby is performed on the client anyway |
…parameter of type 'Microsoft.EntityFrameworkCore.Metadata.IEntityType' Problem was that we made some assumptions when compiling include, that do not hold true for complex queries involving group by and other operations that follow. Once we build _Include(...) expression and try to substitute a qsre with it, we have compensation logic in case of groupby - trying to apply the substitution on the ElementSelector of the groupby. This logic is located in QueryModelExtensions.GetOutputExpression. However, we assume that the outermost query model is the one that contains the groupby result operator. For the queries in the bug, this is not the case - GroupBy result operator is a subquery and therefore our old logic was not detecting it correctly, causing an error. Fix is to find a correct query model (based on the qsre used in the Include result operator) and only after the correct QM (which can be in a subquery) is obtained, perform the compensation logic in QueryModelExtensions.GetOutputExpression. Additional fix is needed when compiling collection navigation includes. We manually craft the QM that fetches child elements, and also assume that the outermost parent QM is the one that needs to be joined to. Similar approach is used here - find the "real" QM referenced in the include and build the collection-fetching QM based on that instead.
…parameter of type 'Microsoft.EntityFrameworkCore.Metadata.IEntityType' Problem was that we made some assumptions when compiling include, that do not hold true for complex queries involving group by and other operations that follow. Once we build _Include(...) expression and try to substitute a qsre with it, we have compensation logic in case of groupby - trying to apply the substitution on the ElementSelector of the groupby. This logic is located in QueryModelExtensions.GetOutputExpression. However, we assume that the outermost query model is the one that contains the groupby result operator. For the queries in the bug, this is not the case - GroupBy result operator is a subquery and therefore our old logic was not detecting it correctly, causing an error. Fix is to find a correct query model (based on the qsre used in the Include result operator) and only after the correct QM (which can be in a subquery) is obtained, perform the compensation logic in QueryModelExtensions.GetOutputExpression. Additional fix is needed when compiling collection navigation includes. We manually craft the QM that fetches child elements, and also assume that the outermost parent QM is the one that needs to be joined to. Similar approach is used here - find the "real" QM referenced in the include and build the collection-fetching QM based on that instead.
…parameter of type 'Microsoft.EntityFrameworkCore.Metadata.IEntityType' Problem was that we made some assumptions when compiling include, that do not hold true for complex queries involving group by and other operations that follow. Once we build _Include(...) expression and try to substitute a qsre with it, we have compensation logic in case of groupby - trying to apply the substitution on the ElementSelector of the groupby. This logic is located in QueryModelExtensions.GetOutputExpression. However, we assume that the outermost query model is the one that contains the groupby result operator. For the queries in the bug, this is not the case - GroupBy result operator is a subquery and therefore our old logic was not detecting it correctly, causing an error. Fix is to find a correct query model (based on the qsre used in the Include result operator) and only after the correct QM (which can be in a subquery) is obtained, perform the compensation logic in QueryModelExtensions.GetOutputExpression. Additional fix is needed when compiling collection navigation includes. We manually craft the QM that fetches child elements, and also assume that the outermost parent QM is the one that needs to be joined to. Similar approach is used here - find the "real" QM referenced in the include and build the collection-fetching QM based on that instead.
…parameter of type 'Microsoft.EntityFrameworkCore.Metadata.IEntityType' Problem was that we made some assumptions when compiling include, that do not hold true for complex queries involving group by and other operations that follow. Once we build _Include(...) expression and try to substitute a qsre with it, we have compensation logic in case of groupby - trying to apply the substitution on the ElementSelector of the groupby. This logic is located in QueryModelExtensions.GetOutputExpression. However, we assume that the outermost query model is the one that contains the groupby result operator. For the queries in the bug, this is not the case - GroupBy result operator is a subquery and therefore our old logic was not detecting it correctly, causing an error. Fix is to find a correct query model (based on the qsre used in the Include result operator) and only after the correct QM (which can be in a subquery) is obtained, perform the compensation logic in QueryModelExtensions.GetOutputExpression. Additional fix is needed when compiling collection navigation includes. We manually craft the QM that fetches child elements, and also assume that the outermost parent QM is the one that needs to be joined to. Similar approach is used here - find the "real" QM referenced in the include and build the collection-fetching QM based on that instead.
Please consider a patch release - on myget, or an alpha on nuget? There are a number of blocking bugs preventing us from migrating to 2.0. A prerelease/patch would help tremendously for now. |
…parameter of type 'Microsoft.EntityFrameworkCore.Metadata.IEntityType' Problem was that we made some assumptions when compiling include, that do not hold true for complex queries involving group by and other operations that follow. Once we build _Include(...) expression and try to substitute a qsre with it, we have compensation logic in case of groupby - trying to apply the substitution on the ElementSelector of the groupby. This logic is located in QueryModelExtensions.GetOutputExpression. However, we assume that the outermost query model is the one that contains the groupby result operator. For the queries in the bug, this is not the case - GroupBy result operator is a subquery and therefore our old logic was not detecting it correctly, causing an error. Fix is to find a correct query model (based on the qsre used in the Include result operator) and only after the correct QM (which can be in a subquery) is obtained, perform the compensation logic in QueryModelExtensions.GetOutputExpression. Additional fix is needed when compiling collection navigation includes. We manually craft the QM that fetches child elements, and also assume that the outermost parent QM is the one that needs to be joined to. Similar approach is used here - find the "real" QM referenced in the include and build the collection-fetching QM based on that instead.
Hi @dannythomas13, @twilliamsgsnetx, @grokky1. We are gathering information on the use of EF Core pre-release builds. You reported this issue shortly after the release of 2.0.0 RTM. It would be really helpful if you could let us know:
Thanks in advance for any feedback. Hopefully this will help us to increase the value of pre-release builds going forward. |
@ajcvickers Hey thanks for looking into this! We upgraded to netcoreapp2.0 a few days after release. We managed to upgrade both ASP.NET Core and EF Core (after dealing with various breaking changes). But then various tests started failing! After much investigating, we realised it wasn't our code, but the new bits (BTW all our problems have something to do with After ensuring it wasn't because of breaking changes, and realsing that the workarounds were too brittle (and reluctance to change our working code), we decided to just cut our losses and go back to 1.1. My thoughts:
Hope to see 2.0.1 soon! 😄 --
So the "stable with hotfixes" would never have new features, only hotfixes. |
@grokky1 Thanks for the feedback. Could you provide some more information on how the EF Core releases are different from what you are suggesting? (It seems what you describe is what is happening, so I am probably missing something.) For example, was there a patch release that included changes you considered to be features? Or is it more that these releases don't come out fast enough? Thanks again for your thoughts. |
@ajcvickers Maybe I'm the one who is confused... 😆 I remember trying one of the myget releases and it fixed something but then something else broke (I guess that's to be expected as it's a alpha/beta after all). I was looking in these forums and noticed others complain about the same thing. Maybe we were all mistaken! So I'm glad you say the release plan works that way. But there should be more docs around this matter. Please correct me if I'm wrong:
How do I get my hands on a hotfix without new features - which nuget do I use? |
@smitpatel What's the status of this issue? |
|
This patch bug is approved for the 2.0.x patch. Please send a PR to the |
@ajcvickers Thanks for that breakdown! I'm sure it's documented somewhere but I didn't know for sure until now. 2.0.1 is coming... excited! |
…ed for parameter of type 'Microsoft.EntityFrameworkCore.Metadata.IEntityType' - Modify QuerySourceTracingExpressionVisitor so that it can return the "deepest" GroupBy QueryModel if one exists. - Update the Include compiler to target the correct QueryModel when GroupBy is in play.
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, |
I am experiencing this bug again on EF Core 3.1. The same code worked on EF Core 2.1 var tmp = await _dbContext.Set<Security>()
.AsNoTracking()
.Include(i => (i as RegularSecurity).Classifications)
.Include(i => (i as ShareClass).SubFund).ThenInclude(i => i.Classifications) .Include(i => (i as ShareClass).SubFund).ThenInclude(i => i.Issuer)
.Include(i => (i as ShareClass).SubFund).ThenInclude(i => i.Sicav)
.Include(i => (i as RegularSecurity).Issuer)
.Where(s => securityIds.Contains(s.Id))
.AsNoTracking()
.ToListAsync(); |
@paillave can you provide full code listing? (i.e. entities and dbcontext) |
@paillave ideally, file a new issue with the info and reference this one. |
@maumar I came across similar issue with @paillave, i don't know if he solved it or not. |
Since updating to v2 I now get the following exception from one of my unit tests:
In order to get the test to pass I have had to change:
to the following:
The text was updated successfully, but these errors were encountered: