c#-实体框架ALTER TABLE语句与FOREIGN KEY约束冲突

关于在Entity Framework中进行数据库更新,首先进行代码迁移,出现此错误:

ALTER TABLE语句与FOREIGN KEY约束“ FK_dbo.Clients_dbo.MedicalGroups_MedicalGroupId”冲突。 数据库“ hrbc”的表“ dbo.MedicalGroups”的列“ Id”中发生了冲突。

这是我的课:

public partial class Client
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int? MedicalGroupId { get; set; }
    [ForeignKey("MedicalGroupId")]
    public virtual MedicalGroups MedicalGroup { get { return _MedicalGroup; } set { _MedicalGroup = value; } }
}

这是我的二等班:

public partial class MedicalGroups
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
}

这是我要申请的迁移:

public override void Up()
{
    AddForeignKey("dbo.Clients", "MedicalGroupId", "dbo.MedicalGroups", "Id");
    CreateIndex("dbo.Clients", "MedicalGroupId");
}
Zaid Iqbal asked 2020-02-13T10:21:49Z
11个解决方案
95 votes

检查数据库中是否没有与FK约束冲突的数据,从而导致创建失败。

Turnkey answered 2020-02-13T10:21:59Z
30 votes

我认为@Cory正在为您提供正确的解决方案,您只是没有花时间进行调查。

在添加迁移代码中,可能会生成迁移

public override void Up()
{
AddColumn("dbo.ClientContacts", "FamilialRelationshipId", c => c.Int(nullable: false));
CreateIndex("dbo.ClientContacts", "FamilialRelationshipId");
AddForeignKey("dbo.ClientContacts", "FamilialRelationshipId", "dbo.FamilialRelationships",        "FamilialRelationshipId");
}

注意nullable:false; 如果您的模型的id是int而不是int? (nullable int)迁移代码会将nullable设置为false。您的模型显示您正在使用默认为0的不可为null的int,并且您可能没有值为0的外键项。

现在,您将必须创建外键表中存在的默认值,或如果不使用SQL Server创建约束,则不检查就创建约束。 但是请记住以下几点:如果使用[DefaultValue(0)]属性装饰属性,则如果指定了默认值,它不会像SQL列添加那样更改现有数据。

我建议您更改模型类以允许可为null的int。然后,在您的种子方法中,针对dbcontext创建一个简单的方法,以使用默认值更新新列,因为数据注释中的[DefaultValue]属性不会修改您的数据。

Add-Migration / Update-Database创建列和约束。接下来,如果希望允许非空int,则修改模型,并假定您将所有行再次更改为外键Add-Migration / Update-database的某个有效值。这为您的模型迁移提供了一条不间断的链。 当您发布到实时站点时,它将在派上用场,因为数据模型更改的流程将保持不变。

  • 希望这可以帮助。
RickIsWright answered 2020-02-13T10:22:48Z
11 votes

此错误表明您违反了外键约束。 为了解决您有一些解决方案

  1. 修正您的数据-WITH NOCHECK表中某处的记录具有一个MedicalGroupId,该记录不存在于MedicalGroups表。 编写查询以找出哪些ID没有存在于MedicalGroups表中,并手动修复数据你自己
  2. 删除外键约束-显然,如果删除外键约束,则不再受此消息的困扰。 不幸的是,数据库将不再强制这种关系,并且将来可能使这个问题变得更糟。
  3. 使用WITH NOCHECK创建约束-您可以使用WITH NOCHECK选项创建外键约束。 此选项告诉SQL Server不要将此约束应用于现有数据。 SQL Server将在以后的任何插入/更新/删除操作中检查此约束。
Cory answered 2020-02-13T10:23:27Z
6 votes

因为您的表不为空,所以出现此问题。因此您应该添加新字段,而不必像外键那样附加它。公共诠释? MedicalGroupId {获取; 组; }。然后在软件包管理控制台中执行update-database命令。然后,使用正确的数据(MedicalGroupsId中存在值)填充此表(客户端)中的字段。插入行以创建外键[ForeignKey(“ MedicalGroupId”)]     公共虚拟MedicalGroups MedicalGroup {get {return _MedicalGroup; }设置{_MedicalGroup =值; }。最后执行update-database命令。 会没事的。

chekib answered 2020-02-13T10:23:49Z
4 votes

对于可能落在这里的其他对象,如果您使用的是Code-First Entity Framework,并且只是尝试向具有现有数据的表中添加新的必需列,则可能有一个非常简单的修复程序。

注意:在执行此操作之前,只知道您需要为所有现有行的新列添加有效值。 在继续操作之前,请考虑将要添加到现有行中的值。 您可能需要提供一个值,该值指示所需的查找表为“无效”或“未知”。

在模型中,通过添加?将列设置为可为空。 在int之后。 保存并编译模型。 运行更新数据库。

例:

[ForeignKey("Title")]
public int? TitleId { get; set; }

在数据库中,通过将NULL值替换为有效的查找值来更新表。 就我而言,我在“标题”查询表中添加了“未知”,然后批量编辑所有行以引用该查询ID。

回到模型中,删除“?” 因此该列不再可以为空。 保存并编译模型,然后运行Update-Database

您现在应该可以进行了。

GrayDwarf answered 2020-02-13T10:24:42Z
2 votes

我得到了我的问题的解决方案。 问题是我的客户表中有“数据”。 因为我的客户表具有不实际存在的medicalgroupid值,所以它给我外键约束错误。

Update Client set MedicalGroupId = NULL
Zaid Iqbal answered 2020-02-13T10:25:03Z
2 votes

使用默认值设置时,我也遇到了这个问题,它具有:

“该对象取决于列ALTER TABLE ALTER COLUMN失败,因为一个或多个对象访问此列”。

最终将AddForeignKey / DropForeignKey移至新的迁移,并在单独的update-database命令中运行它们(不要在一个命令中执行两个迁移,对我来说这失败了。)

    public override void Up()
    {
        CreateTable(
            "dbo.DecisionAccesses",
            c => new
            {
                Id = c.Int(nullable: false),
                Name = c.String(nullable: false, maxLength: 50),
            })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "dbo.DecisionPersonStatus",
            c => new
            {
                Id = c.Int(nullable: false),
                Name = c.String(nullable: false, maxLength: 50),
            })
            .PrimaryKey(t => t.Id);

        AddColumn("dbo.DecisionForm_DecisionFields", "DecisionAccessId", c => c.Int(nullable: false, defaultValue: (int)DecisionAccess.Creator));
        AddColumn("dbo.DecisionMatterPersons", "DecisionPersonStatusId", c => c.Int(nullable: false, defaultValue: (int)DecisionAccess.Creator));
        CreateIndex("dbo.DecisionForm_DecisionFields", "DecisionAccessId");
        CreateIndex("dbo.DecisionMatterPersons", "DecisionPersonStatusId");
        //I moved outcommented to next migration and ran the migrations in separate steps to avoid: (The object is dependent on column ALTER TABLE ALTER COLUMN failed because one or more objects access this column)
        //AddForeignKey("dbo.DecisionForm_DecisionFields", "DecisionAccessId", "dbo.DecisionAccesses", "Id", cascadeDelete: true); 
        //AddForeignKey("dbo.DecisionMatterPersons", "DecisionPersonStatusId", "dbo.DecisionPersonStatus", "Id", cascadeDelete: true);
    }


    public override void Down()
    {
        //Moved to next migration
        //DropForeignKey("dbo.DecisionMatterPersons", "DecisionPersonStatusId", "dbo.DecisionPersonStatus");
        //DropForeignKey("dbo.DecisionForm_DecisionFields", "DecisionAccessId", "dbo.DecisionAccesses");
    }
Sgedda answered 2020-02-13T10:25:32Z
1 votes

假设您的迁移顺序正确,即与外键关联的表将在引用之前创建。 请按照以下步骤操作:

  1. 从SQL Management Studio备份当前数据库(如果需要)
  2. 从SQL Management Studio删除数据库
  3. 在Visual Studio“包管理器控制台”中键入“更新数据库”
Kuldeep Padhiar answered 2020-02-13T10:26:06Z
0 votes

在程序包管理器控制台中运行Add-Migration InitialCreate –IgnoreChanges命令。 这将使用当前模型作为快照创建一个空迁移。

在程序包管理器控制台中运行Update-Database命令。 这会将InitialCreate迁移应用于数据库。 由于实际迁移不包含任何更改,因此只需在__MigrationsHistory表中添加一行,以表明该迁移已被应用。

您可以在此处获得更多详细信息:[https://msdn.microsoft.com/zh-cn/library/dn579398(v=vs.113).aspx]

Ersin answered 2020-02-13T10:26:36Z
0 votes

如果您在子表中有孤立的记录,也会发生此错误。 清理数据库应解决此问题。

Christopher Cabezudo Rodriguez answered 2020-02-13T10:26:56Z
0 votes

我也收到了此消息。 问题是数据库中的测试数据不正确。我没有在测试时进行验证,因此对于不允许为null的字段,ID的值为null。 修复数据后,update-database命令成功运行。

Fabian Madurai answered 2020-02-13T10:27:16Z
translate from https://stackoverflow.com:/questions/20871349/entity-framework-the-alter-table-statement-conflicted-with-the-foreign-key-const