-
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
Wrong mapping of nested complex property with generic types and same property name, resulting in InvalidCastException #33449
Labels
area-complex-types
area-query
closed-fixed
The issue has been fixed and is/will be included in the release indicated by the issue milestone.
customer-reported
Servicing-approved
type-bug
Milestone
Comments
Thanks, confirmed the bug. Minimal reproawait using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
var container = new ComplexContainer
{
Id = 1,
Containee1 = new() { Id = 2 },
Containee2 = new() { Id = 3 }
};
_ = await context.Blogs.Where(b => b.ComplexContainer == container).ToListAsync();
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer("Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().ComplexProperty(b => b.ComplexContainer, x =>
{
x.ComplexProperty(c => c.Containee1);
x.ComplexProperty(c => c.Containee2);
});
}
}
public class Blog
{
public int Id { get; set; }
public ComplexContainer ComplexContainer { get; set; }
}
public class ComplexContainer
{
public int Id { get; set; }
public ComplexContainee1 Containee1 { get; set; }
public ComplexContainee2 Containee2 { get; set; }
}
public class ComplexContainee1
{
public int Id { get; set; }
}
public class ComplexContainee2
{
public int Id { get; set; }
} |
roji
added a commit
to roji/efcore
that referenced
this issue
Apr 12, 2024
roji
added
closed-fixed
The issue has been fixed and is/will be included in the release indicated by the issue milestone.
Servicing-consider
labels
Apr 12, 2024
roji
added a commit
to roji/efcore
that referenced
this issue
Apr 13, 2024
Backporting discussion: data corruption bug, plus customer impact is probably common enough. In addition, the fix is trivial and very low-risk. |
roji
added a commit
that referenced
this issue
Apr 16, 2024
roji
added a commit
to roji/efcore
that referenced
this issue
Apr 16, 2024
…#33527) Fixes dotnet#33449 (cherry picked from commit 89e9446)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
area-complex-types
area-query
closed-fixed
The issue has been fixed and is/will be included in the release indicated by the issue milestone.
customer-reported
Servicing-approved
type-bug
File a bug
I stumbled upon a bug in the
RelationalSqlTranslatingExpressionVisitor.CreatePropertyAccessExpression
I have a
.Where()
query comparing 2 ComplexProperties of a given type:Repro-Repo
I set up a repository to reproduce the error: https://github.com/lucahost/ef-complex-bug-repro
Just adjust the connection string in
Program.cs
and run the sample.Setup
Now in the
RelationalSqlTranslatingExpressionVisitor
inCreatePropertyAccessExpression
the SQL statementsparameterName
forOrderPosition.Recipient.Address.Id
of TypeId<Address>
is generated as following:__entity_equality_orderPosition_Recipient_0_Id
Exception in
RelationalTypeMapping.CreateParameter
Then in the conversion of the parameter to the provider, the wrong cast is being made.
The SQL-parameter
@__entity_equality_orderPosition_Recipient_0_Id
of typeId<Customer>
would be converted toId<Address>
Assumption
As you see, the
Id
property on the complex types are all called the same. I think this is the culprit which results in the parameter not being added correctly.Workarounds
One workaround was to get rid of the nesting ->
OrderPosition.Recipient.AddressId
whereRecipient
is configured asComplexProperty()
andAddresId
as.Property()
.Another one I found out while stepping through the code was by using a distinct parameter-name in
RelationalSqlTranslatingExpressionVisitor.CreatePropertyAccessExpression
. Something along the linesLater is not a solution for everything, but was working in my case.
I think the parameter-name should be generated something like this:
__entity_equality_orderPosition_Recipient_0_Address_Id
including the nested properties name.EF Core version: 8.0.3
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system:
IDE: Rider 2024.1 RC
The text was updated successfully, but these errors were encountered: