gpt4 book ai didi

c# - Entity Framework Core、DELETE CASCADE 和 [必需]

转载 作者:行者123 更新时间:2023-11-30 14:22:30 25 4
gpt4 key购买 nike

我在 Entity Framework Core 中遇到了一个问题 DELETE CASCADE,我似乎找不到好的解决方案。

这是我的模型的 super 简化版本:

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

Recipe 和 Ingredient 都将 UserID 标记为 [Required],而 RecipeIngredient 将 RecipeID 和 IngredientID 标记为 [Required]。

问题是 SQL 不会创建数据库,因为 RecipeIngredient 有多个级联删除路径(“引入 FOREIGN KEY 约束...可能会导致循环或多个级联路径”)。

所以我被困住了......我已经尝试过一些想法,但没有一个是有效的。

  1. 这里有设计解决方案吗?我想保留我的外键,因为强制执行它是有意义的,但如果有设计解决方案,我愿意接受。

  2. 我的下一个想法是删除所有指向用户的 FK - 我必须在 DELETE 期间通过我的 C# 代码强制执行参照完整性,并且我可以在 CREATE 期间使用 [Required] 强制输入数据。问题在于 - [Required] 创建了一个 FK,并添加了“ON DELETE CASCADE”,这让我们又回到了多重级联删除路径问题。我真的很想保留 [Required] 因为与 Razor 页面的巧妙集成、客户端验证和错误等。

  3. 下一个想法,在 OnModelCreating(...) 中将级联行为设置为 SetNull:

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

    模型构建器.Entity() .HasOne(r => r.Source) .WithMany(s => s.Recipes) .OnDelete(DeleteBehavior.SetNull);

但这会引发异常,因为即使我在 Ingredient 和 Recipe 中的属性设置为 Nullable:

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

...由于 [Required] 属性,EF 仍将其创建为 NOT NULL 数据库列。

解决这个问题的方法是什么?据我所知,我应该只删除用户的所有 FK,并尝试将其作为 CREATE 上的必填字段强制执行,但我看不到使用数据注释来做到这一点的方法,我想这样做将此逻辑保留在我的代码优先模型中。

最佳答案

我建议禁用级联删除,因为开发人员通常希望非常小心删除哪些数据,禁用级联删除将使您在删除方面对数据进行更精细的控制。

您可以在 OnModelCreation(DbModelBuilder modelBuilder) 覆盖中执行此操作,如下所示在您的 Context.cs 类中:

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;
}
}

关于c# - Entity Framework Core、DELETE CASCADE 和 [必需],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49326769/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com