如何清除带有外键约束的数据库

本文关键字:约束 数据库 何清除 清除 | 更新日期: 2023-09-27 17:58:13

我希望我的种子方法首先清除/删除数据库并清除所有旧数据,但是

context.Database.ExecuteSqlCommand("TRUNCATE TABLE [Purchases]");
context.Database.ExecuteSqlCommand("TRUNCATE TABLE [Invoices]");

给我

无法截断表"Purchases",因为它正被FOREIGN KEY约束。

因为采购中的分录取决于发票中的分目。如何通过种子方法清除所有数据?

编辑:这些是相关的型号:

public class Invoice
{
    //Primary Key
    public int InvoiceID { get; set; }
    //Misc. info
    public DateTime CreationDate { get; set; }
    public DateTime DeadlineDate { get; set; }
    public string ReceiverName { get; set; }
    //Order details
    public virtual List<Purchase> Purchases { get; set; }
    //Auto-calculated property
    [DataType(DataType.Currency)]
    public float TotalCost { get; set; }
    //Invoice author info
    public string AuthorName { get; set; }
    public string AuthorID { get; set; }
}

public class Purchase
{
    public int PurchaseID { get; set; }
    public string ProductDescription { get; set; }
    public float SinglePrice { get; set; }
    public float Amount { get; set; }
    public float TotalPrice { get { return Amount * SinglePrice; } }
}

如何清除带有外键约束的数据库

有几种解决方案。

  1. 如果您想清理整个数据库,最简单的解决方案就是重新创建整个数据库。更复杂的解决方案是删除外键,清理数据库并创建外键。这可以实现自动化。不手动这样做不是一个好主意。进入下一个选项要好得多。

  2. 知道了数据库结构,就可以按顺序删除数据,这不会违反外键约束。这也可以自动化,但需要付出更多的努力。但是,手动按有效顺序写入TRUNCE非常容易。

    无法截断表"Purchases",因为它正被FOREIGN KEY约束引用。

    在这种情况下,首先确定哪个表引用表Purchases,并在截断Purchases之前清除该表中的数据。

    此外,如果您有循环引用,则无法在不删除(或标记WITH NOCHECK)外键的情况下删除数据。

  3. 你也可以设置级联删除,但我强烈反对,因为你偶尔可以删除你不想删除的数据。

由于种子方法是在更新数据库后调用的,我认为您的方法不起作用。我过去所做的就是执行:

Update-Database -TargetMigration 0

这将把数据库重置为第一次迁移。然后执行:

Update-Database

您需要按照外键约束的顺序清除表。如果"发票"中的外键约束引用了"采购"表,则需要首先截断"发票"。

如果您只是想清除数据以重新播种,agrifin是对的,只需使用-Target-Migration:0重置EF。

如果您试图截断生产数据,则需要先删除外键约束,然后再重新添加它们。真的没有任何办法。

但我在这里的另一个答案中的脚本将快速生成您需要在截断前后添加的ALTER TABLE SQL。我建议将所有操作作为存储过程的一部分:

ALTER TABLE [dbo].[Purchases] DROP CONSTRAINT....
TRUNCATE TABLE [Purchases];
ALTER TABLE [dbo].[Purchases] ADD CONSTRAINT....