C# 实体框架ALTER TABLE语句与外键约束冲突

C# 实体框架ALTER TABLE语句与外键约束冲突,c#,sql,.net,sql-server,entity-framework,C#,Sql,.net,Sql Server,Entity Framework,在实体框架中更新数据库时,代码优先迁移,出现以下错误: ALTER TABLE语句与外键约束“FK_dbo.Clients_dbo.MedicalGroups\u MedicalGroupId”冲突。冲突发生在数据库“hrbc”、表“dbo.MedicalGroups”、列“Id”中 这是我的班级: public partial class Client { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] pu

在实体框架中更新数据库时,代码优先迁移,出现以下错误:

ALTER TABLE语句与外键约束“FK_dbo.Clients_dbo.MedicalGroups\u 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");
}

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

此错误表明您违反了外键约束。要解决这个问题,您有一些解决方案

  • 修复您的数据-在
    客户
    表中的某些记录中,包含的MedicalGroup ID在中不存在
    medicalgroup
    表格。写一个查询,找出哪些ID不需要 存在于
    MedicalGroup
    表中,并手动修复数据 你自己
  • 删除外键约束-显然,如果您删除外键约束,您将不再被此消息困扰。不幸的是,数据库将不再强制执行这种关系,并可能在将来使此问题变得更糟
  • 使用带NOCHECK的
    创建约束
    -您可以使用带NOCHECK的
    选项创建外键约束。此选项告诉SQL Server不要将此约束应用于现有数据。SQL Server将在以后的任何插入/更新/删除中检查此约束

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

    Update Client set MedicalGroupId = NULL
    

    我认为@Cory让你接近了正确的解决方案,你只是没有花时间去调查

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

    public override void Up()
    {
    AddColumn("dbo.ClientContacts", "FamilialRelationshipId", c => c.Int(nullable: false));
    CreateIndex("dbo.ClientContacts", "FamilialRelationshipId");
    AddForeignKey("dbo.ClientContacts", "FamilialRelationshipId", "dbo.FamilialRelationships",        "FamilialRelationshipId");
    }
    
    通知可为空:false;如果您的模型的Id是int而不是int?(nullable int)迁移代码将nullable设置为false。 您的模型显示您正在使用默认为0的不可为null的int,并且您可能没有值为0的外键项

    现在,您必须创建一个存在于外键表中的默认值, 或者,如果正在使用SQL Server创建约束,则在不检查的情况下创建约束。但请记住:如果您使用[DefaultValue(0)]属性装饰属性,则如果指定了默认值,它不会像SQL列Add那样更改现有数据

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

    添加迁移/更新数据库以创建列和约束。 接下来,如果希望允许不可为null的int,并假定已将所有行更改为外键的某个有效值,请修改模型,再次添加迁移/更新数据库。 这在模型移植中为您提供了一条完整的链。当您发布到实时站点时,它将派上用场,因为您的数据模型更改流将保持不变

    • 希望这有帮助

    我在defaultValue set中也遇到了这个问题,给出了:

    “对象依赖于列ALTER TABLE ALTER column失败,因为一个或多个对象访问此列”

    最后,将AddForeignKey/DropForeignKey移动到新的迁移中,并在单独的更新数据库命令中运行它们(不要在一个命令中同时执行两个迁移,否则我会失败。)


    在Package Manager控制台中运行添加迁移初始创建–忽略更改命令。这将创建一个以当前模型作为快照的空迁移

    在Package Manager控制台中运行更新数据库命令。这将对数据库应用InitialCreate迁移。由于实际迁移不包含任何更改,因此它只需向_MigrationsHistory表中添加一行,指示已应用此迁移


    您可以在此处获得更多详细信息:

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

  • 从SQL management studio备份当前数据库(如果需要)
  • 从SQL management studio中删除数据库
  • 在Visual Studio“包管理器控制台”中键入“Update-Database”

  • 对于其他可能出现在这里的情况,如果您使用代码优先实体框架,并且只是尝试向包含现有数据的表中添加一个新的必需列,那么可能会有一个非常简单的修复方法

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

    在模型中,通过添加?完成int之后,保存并编译模型。运行更新数据库

    例如:
    [ForeignKey(“标题”)]
    
    公共整数?TitleId{get;set;}
    出现此问题是因为您的表不是空的。 因此,您应该添加新字段,而不要像外键一样附加它。 公共int?MedicalGroupId{get;set;}
    。并在包管理控制台中执行
    更新数据库
    命令。 然后用正确的数据(值存在于MedicalGroupsId中)填充此表(客户端)中的字段。 插入行以创建外键

    [ForeignKey("MedicalGroupId")]
    public virtual MedicalGroups MedicalGroup { get { return _MedicalGroup; } set { _MedicalGroup = value; } }
    
    最后执行
    更新数据库
    命令。一切正常。

    此错误也可能发生
    [ForeignKey("MedicalGroupId")]
    public virtual MedicalGroups MedicalGroup { get { return _MedicalGroup; } set { _MedicalGroup = value; } }