削除したいユーザーがいるが、そのユーザーがデータベース内の他のテーブルから参照されている可能性があるとします。SaveChanges()
削除を試みる前にこのユーザーへの参照をチェックする方法はありますか、それともスローする例外を削除してキャッチ/処理するための最良のオプションですか?
明らかに、ユーザーが参照される可能性のある各テーブルを確認することはできますが、いくつかの場所で参照されているため、むしろ面倒な方法のように思われます。
削除したいユーザーがいるが、そのユーザーがデータベース内の他のテーブルから参照されている可能性があるとします。SaveChanges()
削除を試みる前にこのユーザーへの参照をチェックする方法はありますか、それともスローする例外を削除してキャッチ/処理するための最良のオプションですか?
明らかに、ユーザーが参照される可能性のある各テーブルを確認することはできますが、いくつかの場所で参照されているため、むしろ面倒な方法のように思われます。
あなたがこれに対する解決策をまだ見つけているかどうかはわかりませんが、私自身も同様の問題に遭遇したので投稿しています。クエリを使用して参照をチェックすると、次のようになります。
bool related = db.Article.Where(i => i.CategoryId == id).Any();
しかし、参照をチェックするよりも、例外をキャッチする方が良いと思います。
必要な関係が必要であるがカスケード削除が必要ないシナリオでは、規則を明示的にオーバーライドし、FluentAPIを使用してカスケード削除動作を構成できます。使用するFluentAPIメソッドはWillCascadeOnDeleteと呼ばれ、パラメーターとしてブール値を取ります。この構成はリレーションシップに適用されます。つまり、最初にHas / Withペアリングを使用してリレーションシップを指定してから、WillCascadeOnDeleteを呼び出す必要があります。何かのようなもの:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Article>()
.HasRequired(a => a.Category)
.WithMany(i => i.Articles)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
次に、データがメモリにロードされる方法に応じて、通常、DbUpdateExceptionまたはInvalidOperationExceptionが発生します。簡単なステートメントでそれらをキャッチし、ユーザーにメッセージを追加できます。
try
{
db.Category.Remove(category);
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DataException)
{
ModelState.AddModelError("", "Your message here");
return View(category);
}
WillCascadeOnDeleteは基本的に、データベースの削除ルールをカスケードからアクションなしに変更し、違反が発生したときにエラーがスローされるようにします。ここでの全体的なメッセージは、カスケード削除設定を制御できるということですが、カスケード削除が存在しないことによって発生する可能性のある競合を回避または解決する責任があります。それは私のために働いた、それがあなたにも役立つことを願っています。参照:FluentAPIとの関係の構成