【问题标题】:EF Core failed to execute database update command : " fail: Microsoft.EntityFrameworkCore.Database.Command[20102] "EF Core 无法执行数据库更新命令:“失败:Microsoft.EntityFrameworkCore.Database.Command[20102]”
【发布时间】:2021-02-17 09:32:43
【问题描述】:

伙计们,我正在尝试运行 dotnet ef database update 命令,但在执行它的过程中,它给了我一个异常:

Failed executing DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [ProductSubCategory] (
    [ProductId] int NOT NULL,
    [SubCategoryId] int NOT NULL,
    CONSTRAINT [PK_ProductSubCategory] PRIMARY KEY ([SubCategoryId], [ProductId]),
    CONSTRAINT [FK_ProductSubCategory_Product_ProductId] FOREIGN KEY ([ProductId]) REFERENCES [Product] ([ProductId]) ON DELETE CASCADE,
    CONSTRAINT [FK_ProductSubCategory_SubCategory_SubCategoryId] FOREIGN KEY ([SubCategoryId]) REFERENCES [SubCategory] ([SubCategoryId]) ON DELETE CASCADE
);
Microsoft.Data.SqlClient.SqlException (0x80131904): Introducing FOREIGN KEY constraint 'FK_ProductSubCategory_SubCategory_SubCategoryId' on table 'ProductSubCategory' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
Introducing FOREIGN KEY constraint 'FK_ProductSubCategory_SubCategory_SubCategoryId' on table 'ProductSubCategory' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.

我在 ASP.NET CORE MVC 应用程序中使用 Sql Server 作为我的数据库提供程序和 Entity framework core 3.19。公平地说,我不确定是什么原因造成的,因为我之前没有遇到过这样的麻烦,一旦我在 all 依赖实体上添加了诸如 public int CategoryId { get; set; } 之类的外键属性(在一个到许多关系),例如产品,因为我之前忘记添加它们,现在我将使用它们来更新产品实体。我正在显示实体和流畅的 api 代码
Product.cs强>

public class Product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
        public Category Category { get; set; }
        public int CategoryId { get; set; } //It's one of the foreign keys properties added
        public Brand Brand { get; set; }
        public int BrandId { get; set; }    //It's one of the foreign keys properties added
        public string ImageName { get; set; }
        public IEnumerable<ProductSubCategory> SubCategories { get; set; }
}

ProductSubCategory.cs

public class ProductSubCategory
{
    public int ProductId { get; set; }
    public Product Product { get; set; }
    public int SubCategoryId { get; set; }
    public SubCategory SubCategory { get; set; }
}

SubCategory.cs

public class SubCategory
{
    public int SubCategoryId { get; set; }
    public string Name { get; set; }
    public int CategoryId { get; set; }
    public Category Category { get; set; }
    [JsonIgnore]
    public IEnumerable<ProductSubCategory> ProductSubCategories { get; set; }
}

Category

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public IEnumerable<Product> Products { get; set; }
    public IEnumerable<SubCategory> SubCategories { get; set; }
}

DbContext.cs

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
modelBuilder.Entity<ProductSubCategory>()
                .HasKey(psc => new {psc.SubCategoryId, psc.ProductId});
            
            modelBuilder.Entity<ProductSubCategory>()
                .HasOne(psc => psc.Product)
                .WithMany(p => p.SubCategories)
                .HasForeignKey(psc => psc.ProductId);

            modelBuilder.Entity<ProductSubCategory>()
                .HasOne(psc => psc.SubCategory)
                .WithMany(sc => sc.ProductSubCategories)
                .HasForeignKey(psc => psc.SubCategoryId);
}

我很确定我正确配置了关系。
我尝试过的事情:

  1. 删除迁移文件夹并创建一个新文件夹。
  2. 将 Ef Core nuget 包更新到最新版本
  3. 删除数据库,然后创建一个新的。

PD:我需要帮助,我没时间了,如果你想要实体项目的源代码及其各自的 Dbcontext,我可以给你,但正如我所说,它有 19 个实体类。
这是源代码:https://github.com/ToastedGuy2/Food-Town-issue
编辑: 真正的问题是如何删除每个外键中的 On Cascade On Delete?不管是一对多还是多对多关系。

【问题讨论】:

  • 错误告诉您问题:“在表 'ProductSubCategory' 上引入 FOREIGN KEY 约束 'FK_ProductSubCategory_SubCategory_SubCategoryId' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION ,或修改其他 FOREIGN KEY 约束。"
  • 哪一部分?错误很清楚,解决方案也很明确。
  • 只搜索“循环或多级联路径”
  • 好的,让我们开始吧,“可能导致循环或多级联路径”这句话有什么不妥之处?那么,在这之后,“Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraint.”的哪一部分。你不明白吗?哪些具体部分让您感到困惑?
  • 类别和子类别有什么区别?为什么你在一个类中有 CategoryId 和 SubCategoryId。 Category 类在哪里?

标签: c# sql-server .net-core entity-framework-core dbcontext


【解决方案1】:

在表“ProductSubCategory”上引入 FOREIGN KEY 约束“FK_ProductSubCategory_SubCategory_SubCategoryId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

该错误实际上是在告诉您这里的问题。我不确定哪一点不清楚,因为 OP 表示他们什么都不懂(我必须承认这意味着语言障碍,因此我建议更改您的 LOGIN 的语言以使用您更熟悉的语言来获取错误与),但是,我将过度“愚蠢”下来:

引入 FOREIGN KEY 约束“FK_ProductSubCategory_SubCategory_SubCategoryId”

这是在谈论您尝试创建的 FOREIGN KEY FK_ProductSubCategory_SubCategory_SubCategoryId

在表“ProductSubCategory”上

这告诉你前面提到的FOREIGN KEY 正在尝试在表上创建ProductSubCategory

可能导致循环或多个级联路径。

这意味着试图在上述TABLE 上创建的上述FOREIGN KEY 将导致循环或多个级联路径。

  • 循环意味着DELETE 将导致对同一张表的进一步删除,在同一张表上触发更多删除,在同一张表上触发更多删除,...在同一张表上触发更多删除,.. .(你明白了)
  • Multiple Cascade Paths 意味着将有多个其他表将从中删除行,现在 SQL Server 允许这样做;特别是如果他们稍后会聚在同一张桌子上。

指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION

我真的不知道如何进一步澄清这一点。而不是ON CASCADE 使用NO ACTION。 AKA,自己处理级联。

或修改其他 FOREIGN KEY 约束

再一次,这很能告诉你该怎么做。修改你桌子上的其他CONSTRAINTs,使它们不会造成循环或多路径;必须可能通过将该密钥更改为NO ACTION 并自己处理级联。

【讨论】:

  • 感谢您抽出宝贵时间。我如何指定ON Delete NO Action?因为我注意到整个项目都有它们,而且公平地说,它不应该有它们,所以我基本上必须告诉 ef core,删除它,但是如何?只是为了提供更多上下文,在我的项目中我不删除记录,我只是禁用它们,使用 isItActive 布尔属性。
  • 问题:EF Core 如何知道外键是否为ON DELETE CASCADE OR NO ACTION。因为在多对多关系上,它默认添加,我只是按照其他页面所说的约定。当谈到一对多的关系时,我遵循了本页的第 4 条约定:entityframeworktutorial.net/efcore/…。基本上它说:在依赖实体中使用外键属性在两端完全定义关系会创建一对多关系。
【解决方案2】:

尝试改变

 modelBuilder.Entity<ProductSubCategory>()
                .HasOne(psc => psc.Product)
                .WithMany(p => p.SubCategories)
                .HasForeignKey(psc => psc.ProductId);

 modelBuilder.Entity<ProductSubCategory>()
                .HasOne(psc => psc.Product)
                .WithMany(p => p.ProductSubCategories)
                .HasForeignKey(psc => psc.ProductId);

而且我通常使用 .OnDelete(DeleteBehavior.ClientSetNull)

【讨论】:

  • Serge,SubCategories 属性基本上有一个 ProductSubCategories 的列表。所以我不明白你从哪里得到ProductSubCategories。我想我应该再次重命名属性,这样会更清楚。
  • 代码中的下一条记录 modelBuilder.Entity() .HasOne(psc => psc.SubCategory) .WithMany(sc => sc.ProductSubCategories) .HasForeignKey(psc => psc. SubCategoryId);
  • 我的意思是关系很好配置,我只需要删除我外键上的所有ON DELETE CASCADE
  • 好的,我去试试。
【解决方案3】:

EF Core 默认为级联删除。一旦你有太多的问题,这就会开始导致问题,而且你也不希望它们到处都是。

在定义您的关系时,您应该尝试自己默认为无级联,除非您确实需要级联。

entityBuilder
.HasMany(one => one.Many)
.WithOne(many => many.One)
.OnDelete(DeleteBehavior.NoAction);

【讨论】:

    猜你喜欢
    • 2020-08-17
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    相关资源
    最近更新 更多