Skip to content

ComplexProperty and OwnsMany/AutoInclude #32595

Open

Description

.Net8
Microsoft.EntityFrameworkCore 8.0.0.
Microsoft.EntityFrameworkCore.SqlServer 8.0.0

When using ComplexProperty with OwnsMany entity, the request is not formed correctly

Example

Model

 public class Parent
 {
     public long Id { get; set; }

     public ValueObject Value { get; set; }

     public List<Child> Children { get; set; }
 }

public class Child
{
    public long Id { get; set; }

    public long ParentId { get; set; }

    public int Value { get; set; }
}

public class ValueObject
{
    public int Field1 { get; set; }

    public int Field2 { get; set; }
}

API Fluent

public class ParentConfiguration : IEntityTypeConfiguration<Parent>
{
    public void Configure(EntityTypeBuilder<Parent> builder)
    {
        builder.ToTable(nameof(Parent));

        builder.HasKey(x => x.Id);
        builder.Property(x=>x.Id).ValueGeneratedNever();
//!!!!
        builder.ComplexProperty(x => x.Value, bd =>
        {
            bd.IsRequired();
            bd.Property(x => x.Field1).IsRequired();
            bd.Property(x => x.Field2).IsRequired();
        });
//!!!!
        builder.OwnsMany(x => x.Children, ba =>
        {
            ba.ToTable(nameof(Child));
             ba.HasKey(x=>x.Id);
             ba.WithOwner().HasForeignKey(x=>x.ParentId);
            
             ba.Property(x=>x.Id);
             ba.Property(x => x.ParentId);
             ba.Property(x => x.Value).IsRequired();
        });
    }
}

Linq1:

await parentContext.Parents.Select(x => new
{
    Field1 = x.Value.Field1,
    Field2 = x.Value.Field2,
}).ToListAsync();

Result1:

SELECT [p].[Id], [p].[Value_Field1], [p].[Value_Field2], [c].[ChildId], [c].[ParentId], [c].[Value], [c0].[ChildId], [c0].[ParentId], [c0].[Value]
FROM [Parent] AS [p]
LEFT JOIN [Child] AS [c] ON [p].[Id] = [c].[ParentId]
LEFT JOIN [Child] AS [c0] ON [p].[Id] = [c0].[ParentId]
ORDER BY [p].[Id], [c].[ChildId]

Linq2:

await parentContext.Parents.Select(x => new
{
     Field1 = x.Value.Field1,
}).ToListAsync();

Result2:

SELECT [p].[Id], [p].[Value_Field1], [p].[Value_Field2], [c].[ChildId], [c].[ParentId], [c].[Value]
FROM [Parent] AS [p]
LEFT JOIN [Child] AS [c] ON [p].[Id] = [c].[ParentId]
ORDER BY [p].[Id]

Linq3:

await parentContext.Parents.Select(x => new
{
    Id = x.Id,
}).ToListAsync()

Result3:

SELECT [p].[Id]
FROM [Parent] AS [p]

Thus, the first and second examples make unnecessary join in SQL. Their number depends on the number of calls to values from ComplexProperty.
This behavior occurs when using OwnsMany or AutoInclude

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions