SQL Server Database.EnsureCreated() fails on foreign key creation

eh57zj3b  于 2024-01-05  发布在  其他
关注(0)|答案(1)|浏览(94)

I am trying to create a database on a docker image to use for testing. In my Startup.cs, I added the following:

if (env.IsDevelopment())
            {
                using var scope = app.ApplicationServices.CreateScope();
                Application.SetupContext(scope.ServiceProvider);
                using var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
                context.Database.EnsureDeletedAsync().Wait();
                context.Database.EnsureCreatedAsync().Wait();
                SqliteDbSeeder.SeedTestDatabase(context);
            }

I am getting an exception when it tries to create the Addresses table:

Failed executing DbCommand ("18"ms) [Parameters=[""], CommandType='Text',
CommandTimeout='30']"\r\n""CREATE TABLE [Addresses] (\r\n    [Id] int NOT NULL,\r\n  
[CareOf] nvarchar(500) NULL,\r\n    [Address] nvarchar(500) NULL,\r\n    [AptSte] 
nvarchar(255) NULL,\r\n    [City] nvarchar(255) NULL,\r\n    [StateProvince] nvarchar(255) 
NULL,\r\n    [ZipPostalCode] nvarchar(10) NULL,\r\n    [Country] nvarchar(255) NULL,\r\n 
CONSTRAINT [PK_dbo.ContactMechanisms] PRIMARY KEY ([Id]),\r\n    CONSTRAINT 
[FK_Addresses_ContactMechanisms_Id] FOREIGN KEY ([Id]) REFERENCES [ContactMechanisms] 
([Id])\r\n);"

There is already an object named 'PK_dbo.ContactMechanisms' in the database.

I have a ContactMechanism entity which is extended by a few classes, i.e. PhoneNumber, Address. EF Core is automatically generating the constraint names but since this key is a constraint on multiple tables it is causing an error. I tried using entity.HasKey(e => e.Id).HasName("PK_dbo.Addresses"); , but then it says 'A key cannot be configured on 'Address' because it is a derived type. The key must be configured on the root type 'ContactMechanism'. I also tried this modelBuilder.Entity<Address>().HasBaseType<ContactMechanism>(); but it causes the same original error.

Is there a way to handle this issue, or do I need to set up the database another way? Note: I did not design this database and the design cannot be changed.

ltskdhd1

ltskdhd11#

This is due to the way how EF handles inheritance and PK's in derived entities.

Address is a derived type of ContactMechanism and EF is trying to create a PK for Address that already exists in ContactMechanism.

I believe explicit key configuration is a solution here, by using the FluentApi way through OnModelCreating() method. Explicitly set the keys. See documentation on Fluent Api here

相关问题