簡體   English   中英

實體框架核心,DELETE CASCADE和[必需]

[英]Entity Framework Core, DELETE CASCADE, and [Required]

我遇到了Entity Framework Core中的問題DELETE CASCADE,我似乎無法找到一個好的解決方案。

這是我的模型的超簡化版本:

User {UserID, Name}
Recipe {RecipeID, UserID}
Ingredient {IngredientID, UserID}
RecipeIngredient {RecipeID, IngredientID} *RecipeIngredient is the many-to-many table.

配方和成分都將UserID標記為[Required],RecipeIngredient將RecipeID和IngredientID標記為[Required]。

問題是SQL不會創建數據庫,因為RecipeIngredient有多個級聯刪除路徑(“引入FOREIGN KEY約束......可能導致循環或多個級聯路徑”)。

所以我被困了......我已經完成了一些想法,但沒有任何方法可行。

  1. 這里有設計方案嗎? 我想保留我的外鍵,因為它是有意義的強制執行它,但如果有一個設計解決方案,我願意接受它。

  2. 我的下一個想法是刪除指向用戶的所有FK - 我必須通過我的C#代碼在DELETE期間強制執行參照完整性,並且我可以在CREATE期間使用[Required]強制執行數據輸入。 問題 - [必需]創建一個FK,並添加“ON DELETE CASCADE”,這使我們回到多個級聯刪除路徑問題。 我真的想保留[必需]因為與Razor頁面的光滑集成,客戶端驗證和錯誤等。

  3. 接下來的想法,在OnModelCreating(...)中將級聯行為設置為SetNull:

    modelBuilder.Entity()。 HasOne(i => i.User).WithMany(u => u.Ingredients).OnDelete(DeleteBehavior.SetNull);

    modelBuilder.Entity()。HasOne(r => r.Source).WithMany(s => s.Recipes).OnDelete(DeleteBehavior.SetNull);

但這引發了異常,因為即使我在Ingredient and Recipe中的屬性設置為Nullable:

[Required(ErrorMessage = "User ID is required.")] 
public Nullable<int> UserID { get; set; }

...由於[Required]屬性,EF仍然將其創建為NOT NULL數據庫列。

這是什么解決方案? 據我所知,我應該刪除所有FK到User,並嘗試將其強制執行為CREATE中的必填字段,但我沒有看到使用數據注釋的方法,我想做將此邏輯保留在我的代碼第一個模型中。

我建議禁用級聯刪除,因為通常開發人員要非常小心刪除哪些數據,並且禁用將使您在刪除數據時對數據進行更細粒度的控制。

您可以在Context.cs類中的OnModelCreation(DbModelBuilder modelBuilder)覆蓋中執行以下操作:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);

  modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
  modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
}

在EF Core中, Conventions類不可用,因此您需要遍歷實體類型並限制刪除以實現所需的效果:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);

  foreach (var relationship in builder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
  {
        relationship.DeleteBehavior = DeleteBehavior.Restrict;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM