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

OwnsMany generates multiple delete statements instead of a single SQL statement (EF Core 7.0.4) #30590

Closed
HamidEbr opened this issue Mar 28, 2023 · 2 comments

Comments

@HamidEbr
Copy link

I have a WatchCategoryEntity class that has a collection of WatchCategorySymbolEntity child entities defined using OwnsMany in my EF Core 5 configuration:

public class WatchCategoryEntity : BaseShardEntity, IAggregateRoot
{
    // ...

    private readonly List<WatchCategorySymbolEntity> _watchCategorySymbols = new();
    public IReadOnlyList<WatchCategorySymbolEntity> WatchCategorySymbols => _watchCategorySymbols;

    public void DeleteSymbolRange(IEnumerable<string> symbolIsins)
    {
        _watchCategorySymbols.RemoveAll(s => symbolIsins.Contains(s.SymbolIsin));
    }

    // ...
}

public class WatchCategorySymbolEntity
{
    public string SymbolIsin { get; init; }
}

internal sealed class WatchCategoryConfig : IEntityTypeConfiguration<WatchCategoryEntity>
{
    public void Configure(EntityTypeBuilder<WatchCategoryEntity> builder)
    {
        builder.Property(p => p.Id).HasColumnType("char(32)");
        builder.Property(p => p.Name).HasColumnType("nvarchar").IsUnicode().HasMaxLength(200).IsRequired();
        builder.Property(p => p.Order).IsRequired(false);
        builder.Property(p => p.IsDefault).IsRequired();
        builder.OwnsMany(p => p.WatchCategorySymbols,
            b =>
            {
                b.WithOwner().HasForeignKey("WatchCategoryId");
                b.ToTable("WatchCategorySymbols");
                b.Property("Id").HasColumnType("bigint");
                b.Property(i => i.SymbolIsin).HasMaxLength(12);
            });

        var navigation = builder.Metadata.FindNavigation(nameof(WatchCategoryEntity.WatchCategorySymbols));
        navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
    }
}

When I call DeleteSymbolRange on a WatchCategoryEntity instance and then call SaveChangesAsync() on my DbContext, EF Core generates multiple delete statements instead of a single SQL statement. I expect EF Core to generate a single SQL statement with a DELETE...IN clause for better performance.

Is there any way to configure EF Core to generate a single delete statement instead of multiple delete statements when deleting child entities with OwnsMany? Or is there any workaround that can achieve the same result?

@HamidEbr HamidEbr changed the title OwnsMany generates multiple delete statements instead of a single SQL statement (EF Core 7) OwnsMany generates multiple delete statements instead of a single SQL statement (EF Core 7.0.4) Mar 28, 2023
@roji
Copy link
Member

roji commented Mar 28, 2023

Duplicate of #27550

@roji roji marked this as a duplicate of #27550 Mar 28, 2023
@roji
Copy link
Member

roji commented Mar 28, 2023

Note that although EF currently generates multiple DELETE statements instead of one, those multiple statements are batched together in a single roundtrip, so the overall perf difference isn't that huge.

@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants