C# 实体框架ALTER TABLE语句与外键约束冲突
在实体框架中更新数据库时,代码优先迁移,出现以下错误: ALTER TABLE语句与外键约束“FK_dbo.Clients_dbo.MedicalGroups\u MedicalGroupId”冲突。冲突发生在数据库“hrbc”、表“dbo.MedicalGroups”、列“Id”中 这是我的班级: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
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的选项创建外键约束。此选项告诉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,并假定已将所有行更改为外键的某个有效值,请修改模型,再次添加迁移/更新数据库。
这在模型移植中为您提供了一条完整的链。当您发布到实时站点时,它将派上用场,因为您的数据模型更改流将保持不变
- 希望这有帮助
在Package Manager控制台中运行添加迁移初始创建–忽略更改命令。这将创建一个以当前模型作为快照的空迁移 在Package Manager控制台中运行更新数据库命令。这将对数据库应用InitialCreate迁移。由于实际迁移不包含任何更改,因此它只需向_MigrationsHistory表中添加一行,指示已应用此迁移
您可以在此处获得更多详细信息:假设您的迁移顺序正确,即与外键关联的表将在引用之前创建。请按照以下步骤操作:
对于其他可能出现在这里的情况,如果您使用代码优先实体框架,并且只是尝试向包含现有数据的表中添加一个新的必需列,那么可能会有一个非常简单的修复方法 注意:在执行此操作之前,只需知道需要为所有现有行的新列添加有效值。在继续之前,请考虑将向现有行添加什么值。您可能希望为所需的查找表提供一个指示“无效”或“未知”的值 在模型中,通过添加?完成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; } }