提问者:小点点

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


在更新实体框架中的数据库时,代码首先迁移,我得到以下错误:

ALTER TABLE语句与FOREIGN KEY约束“FK_dbo.Clients_dbo.MedicalGroups_MedicalGroupId”冲突。冲突发生在数据库“hrbc”、表“dbo.医疗组”、列“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");
}

共3个答案

匿名用户

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

匿名用户

我认为@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的不可为空的int,并且您可能没有值为0的外键项。

现在,您必须创建一个存在于外键表中的默认值,或者如果您使用的是 SQL Server 创建约束,则必须创建不进行任何检查的“创建约束”。但请记住:如果使用 [DefaultValue(0)] 属性修饰属性,则在指定默认值时,它不会像 SQL 列添加那样更改现有数据。

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

添加迁移/更新数据库以创建列和约束。接下来,如果您希望允许不可为空的 int,并假设您将所有行更改为外键的某个有效值,请再次修改模型 Add-Migration / Update-database。这为模型迁移提供了不间断的链。稍后发布到实时站点时将派上用场,因为数据模型更改的流将保持不变。

  • 希望这有帮助。

匿名用户

这个错误告诉您您违反了外键约束。要解决这个问题,您有几个解决方案

  1. 修复您的数据-Clients表中的某个地方有一条记录,其中包含一个在医疗组表中不存在的医疗组ID。编写查询以找出医疗组表中不存在哪些ID,并自己手动修复数据。
  2. 删除外键约束-显然,如果您删除外键约束,您将不再受此消息的困扰。不幸的是,数据库将不再强制执行此关系,并可能在未来使此问题变得更糟。
  3. 使用和NOCHECK创建约束-您可以使用和NOCHECK选项创建外键约束。此选项告诉SQL服务器不要将此约束应用于存量数据。SQL服务器将在将来的任何INSERTS/UPDATES/DELETES中检查此约束。