由于您没有指明您使用的是哪个 EF 版本,让我们看看当前的两个版本,EF 6.2.0 和 EF-core 2.2.4。
使用 EF6,这很容易。映射...
modelBuilder.Entity<A>().HasRequired(a => a.B1).WithMany();
modelBuilder.Entity<A>().HasRequired(a => a.B2).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<B>().HasRequired(b => b.A1).WithMany().WillCascadeOnDelete(false);
...生成以下数据库模型(忽略索引):
CREATE TABLE [dbo].[A] (
[ID] [int] NOT NULL IDENTITY,
[B1_ID] [int] NOT NULL,
[B2_ID] [int] NOT NULL,
CONSTRAINT [PK_dbo.A] PRIMARY KEY ([ID])
)
CREATE TABLE [dbo].[B] (
[ID] [int] NOT NULL IDENTITY,
[A1_ID] [int] NOT NULL,
CONSTRAINT [PK_dbo.B] PRIMARY KEY ([ID])
)
....其中_字段为外键,其中一个可以级联删除。
使用 ef-core,看起来并不那么简单,甚至是错误的。第一个脉冲是等效的 EF6:
modelBuilder.Entity<A>().HasOne(a => a.B1).WithMany();
modelBuilder.Entity<A>().HasOne(a => a.B2).WithMany();
modelBuilder.Entity<B>().HasOne(b => b.A1).WithMany();
但是生成的模型并不是人们所期望的:
CREATE TABLE [B] (
[ID] int NOT NULL IDENTITY,
[A1ID] int NULL,
CONSTRAINT [PK_B] PRIMARY KEY ([ID])
);
CREATE TABLE [A] (
[ID] int NOT NULL,
[B1ID] int NULL,
CONSTRAINT [PK_A] PRIMARY KEY ([ID]),
CONSTRAINT [FK_A_B_B1ID] FOREIGN KEY ([B1ID]) REFERENCES [B] ([ID]) ON DELETE NO ACTION,
CONSTRAINT [FK_A_B_ID] FOREIGN KEY ([ID]) REFERENCES [B] ([ID]) ON DELETE CASCADE
);
ALTER TABLE [B] ADD CONSTRAINT [FK_B_A_A1ID] FOREIGN KEY ([A1ID]) REFERENCES [A] ([ID]) ON DELETE NO ACTION;
A-B 关联之一被解释为 1:1。在我看来,这是一个错误。 WithMany 指令不应留下任何解释空间。两个看似相同的映射会产生完全不同的数据库关系。这不可能。
也就是说,通过命名 FK 列很容易(但不是必需的)使 EF 走上正轨:
modelBuilder.Entity<A>().HasOne(a => a.B1).WithMany().HasForeignKey("B1_ID")
.IsRequired();
modelBuilder.Entity<A>().HasOne(a => a.B2).WithMany().HasForeignKey("B2_ID")
.IsRequired().OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<B>().HasOne(b => b.A1).WithMany().HasForeignKey("A1_ID")
.IsRequired().OnDelete(DeleteBehavior.Restrict);
生产(忽略索引):
CREATE TABLE [B] (
[ID] int NOT NULL IDENTITY,
[A1_ID] int NOT NULL,
CONSTRAINT [PK_B] PRIMARY KEY ([ID])
);
CREATE TABLE [A] (
[ID] int NOT NULL IDENTITY,
[B1_ID] int NOT NULL,
[B2_ID] int NOT NULL,
CONSTRAINT [PK_A] PRIMARY KEY ([ID]),
CONSTRAINT [FK_A_B_B1_ID] FOREIGN KEY ([B1_ID]) REFERENCES [B] ([ID]) ON DELETE CASCADE,
CONSTRAINT [FK_A_B_B2_ID] FOREIGN KEY ([B2_ID]) REFERENCES [B] ([ID]) ON DELETE NO ACTION
);
ALTER TABLE [B] ADD CONSTRAINT [FK_B_A_A1_ID] FOREIGN KEY ([A1_ID]) REFERENCES [A] ([ID]) ON DELETE NO ACTION;
请注意,必须明确设置外键字段(如果需要)。嗯,这只是一个实现细节。