dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.79k stars 3.19k forks source link

EFCore 7 - SqlServer - Git test TPTTableSplittingSqlServerTest.Can_query_shared is generating different foreign key constraint when compared to EFCore 6 #29564

Open shvmgpt116 opened 2 years ago

shvmgpt116 commented 2 years ago

Git test TPTTableSplittingSqlServerTest.Can_query_shared is generating following create table script for table 'CombustionEngines'.

CREATE TABLE [CombustionEngines] (
    [VehicleName] nvarchar(450) NOT NULL,
    [FuelType] nvarchar(max) NULL,
    [Capacity] int NULL,
    CONSTRAINT [PK_CombustionEngines] PRIMARY KEY ([VehicleName]),
    CONSTRAINT [FK_CombustionEngines_PoweredVehicles_VehicleName] FOREIGN KEY ([VehicleName]) REFERENCES [PoweredVehicles] ([Name]) ON DELETE CASCADE,
    CONSTRAINT [FK_CombustionEngines_PoweredVehicles_VehicleName1] FOREIGN KEY ([VehicleName]) REFERENCES [PoweredVehicles] ([Name])
);

Where it is having 2 foreign key constraint for column VehicleName, both referencing PoweredVehicles.Name.

While in EFCore 6 the same test used to generate following create table script.

CREATE TABLE [CombustionEngines] (
    [VehicleName] nvarchar(450) NOT NULL,
    [FuelType] nvarchar(max) NULL,
    [Capacity] int NULL,
    CONSTRAINT [PK_CombustionEngines] PRIMARY KEY ([VehicleName]),
    CONSTRAINT [FK_CombustionEngines_PoweredVehicles_VehicleName] FOREIGN KEY ([VehicleName]) REFERENCES [PoweredVehicles] ([Name])
);

When looking at the entity classes and relationship defined for the entities, I don't see any difference b/w EFCore 6 and EFCore 7. Here is what I see OnModelCreating for the entity.

modelBuilder.Entity<FuelTank>(
                eb =>
                {
                    eb.ToTable("CombustionEngines");

                    eb.HasOne(e => e.Engine)
                        .WithOne(e => e.FuelTank)
                        .HasForeignKey<FuelTank>(e => e.VehicleName)
                        .OnDelete(DeleteBehavior.ClientCascade);
                    eb.HasOne(e => e.Vehicle)
                        .WithOne()
                        .HasForeignKey<FuelTank>(e => e.VehicleName)
                        .OnDelete(DeleteBehavior.ClientCascade);
                });

I am wandering why the create table script has now changed in EFCore 7. Is this an issue or is this expected? If this is expected, what does it mean having 2 foreign keys constraint for same column? Please could someone clarify.

CONSTRAINT [FK_CombustionEngines_PoweredVehicles_VehicleName] FOREIGN KEY ([VehicleName]) REFERENCES [PoweredVehicles] ([Name]) ON DELETE CASCADE,
CONSTRAINT [FK_CombustionEngines_PoweredVehicles_VehicleName1] FOREIGN KEY ([VehicleName]) REFERENCES [PoweredVehicles] ([Name])

EF Core version: 7.0.0 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: NET 6.0 Operating system: Windows 10 IDE: Visual Studio 2022 17.2.6

ajcvickers commented 2 years ago

@shvmgpt116 Looks like a bug.

ajcvickers commented 1 year ago

Note for triage: possibly related to #24970. There is no column duplication here, only constraint duplication. One constraint has cascade delete.