エンティティフレームワークのコード優先でリンクテーブルのカスケード削除を無効にしたい。たとえば、多くのユーザーが多くのロールを持っている場合、ロールを削除しようとすると、その削除をブロックする必要がありますnlessそのロールに現在関連付けられているユーザーはいません。私はすでにOnModelCreating
のカスケード削除規則を削除しています:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
...
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
次に、ユーザーとロールのリンクテーブルを設定します。
modelBuilder.Entity<User>()
.HasMany(usr => usr.Roles)
.WithMany(role => role.Users)
.Map(m => {
m.ToTable("UsersRoles");
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
});
それでも、EFはデータベースを作成するときに、外部キー関係の削除カスケードを作成します。
ALTER TABLE [dbo].[UsersRoles] WITH CHECK ADD CONSTRAINT [FK_dbo.UsersRoles_dbo.User_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([UserId])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[UsersRoles] WITH CHECK ADD CONSTRAINT [FK_dbo.UsersRoles_dbo.Role_RoleId] FOREIGN KEY([RoleId])
REFERENCES [dbo].[Role] ([RoleId])
ON DELETE CASCADE
GO
この削除カスケードを生成するEFを停止するにはどうすればよいですか?
私は答えを得ました。 :-) ManyToManyCascadeDeleteConvention
が原因で、これらのカスケード削除が作成されていました。リンクテーブルのカスケード削除を作成しないように、この規則を削除する必要があります。
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
Ebram Khalilに同意します。1つのテーブルでそれをオフにするのが良い選択肢です。ただし、できる限り自動構築された移行に近づけるのが好きなので、OnModelCreatingで設定します。
_modelBuilder.Entity<User>()
.HasMany(usr => usr.Roles)
.WithMany(role => role.Users)
.Map(m => {
m.ToTable("UsersRoles");
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
})
.WillCascadeOnDelete(false);
_
これは削除が他の方向に進むと保存するため、両方をブロックする必要がある場合(この例では理にかなっています)、Entity<User>(Role)
で始まる同様の呼び出しを行う必要があります。
もちろん、これは質問が行われた後の年齢になります。したがって、2012年には有効ではなかった可能性があります。
ManyToManyCascadeDeleteConvention
をグローバルにオフにするのは賢明なオプションではないと思います。代わりに、オフにすることをお勧めします関係者のみテーブル。
これは、プロパティcascadeDelete
の生成された移行ファイルを編集することで実現できます。例えば:
AddForeignKey("dbo.UsersRoles", "UserId", "dbo.User", "UserId", cascadeDelete: false);