【问题标题】:How to clear a database with foreign key constraints?如何清除具有外键约束的数据库?
【发布时间】:2016-08-04 08:22:29
【问题描述】:

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

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

【问题讨论】:

    标签: c# sql


    【解决方案1】:

    有几种解决方案。

    1. 如果要清理整个数据库,最简单的解决方案就是重新创建整个数据库。更复杂的解决方案是删除外键,清理数据库并再次创建前八个键。这可以自动化。手动执行此操作不是一个好主意。最好继续下一个选项。

    2. 了解您的数据库结构后,您可以按顺序删除数据,这不会违反外键约束。这也可以自动化,但需要付出更多努力。但是手动按有效顺序写TRUNCEs 是不是很容易。

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

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

      如果你有循环引用,也没有办法在不删除(或标记WITH NOCHECK)外键的情况下删除数据。

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

    【讨论】:

    • 级联删除有效,谢谢。我之前没有尝试过,因为它不允许我在 DbSet 上执行 for 循环,而且我认为您无法在 foreach 循环中删除查询集合的成员,但显然我错了。干杯。
    【解决方案2】:

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

    Update-Database -TargetMigration 0
    

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

    Update-Database
    

    【讨论】:

    • 啊,好点,我以为他需要对生产数据库进行截断,我没有意识到这只是清理 EF
    • 这将执行降级方法,但如果数据插入到迁移之外,则不会删除。
    • Down 方法之一将包括 DROP TABLE.... 这将删除任何/所有数据.....
    【解决方案3】:

    您需要按照外键约束的顺序清除表。如果您的 Purchases 表被 Invoices 中的外键约束引用,您需要先截断 Invoices。

    【讨论】:

      【解决方案4】:

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

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

      但是my other answer here 中的脚本会快速生成您需要在截断前后添加的ALTER TABLE SQL。我建议将这一切作为存储过程的一部分:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-20
        • 1970-01-01
        • 1970-01-01
        • 2011-04-09
        • 2021-11-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多