Entity Framework The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
在实体框架中更新数据库,代码优先迁移,我收到此错误:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint"FK_dbo.Clients_dbo.MedicalGroups_MedicalGroupId". The conflict occurred in database"hrbc", table"dbo.MedicalGroups", column 'Id'.
这是我的班级:
1 2 3 4 5 6 7 8 9 10 11 | 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; } } } |
这是我的第二堂课:
1 2 3 4 5 6 | public partial class MedicalGroups { [Key] public int Id { get; set; } public string Name { get; set; } } |
这是我试图应用的迁移:
1 2 3 4 5 | public override void Up() { AddForeignKey("dbo.Clients","MedicalGroupId","dbo.MedicalGroups","Id"); CreateIndex("dbo.Clients","MedicalGroupId"); } |
检查数据库中是否存在与FK约束冲突的现有数据,从而导致创建失败。
我认为@Cory让你接近正确的解决方案,你只是没有花时间去调查。
在添加迁移代码中,可能会生成迁移
1 2 3 4 5 6 | 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。
您的模型显示您使用的是不可为空的int,默认为0,并且您可能没有值为0的外键项。
现在,您必须创建一个默认值,该值存在于外键表中,
或创建约束而不检查是否使用SQL Server创建约束。但请记住:如果使用[DefaultValue(0)]属性装饰属性,则如果指定了默认值,则不会更改现有数据,如SQL Column Add。
我建议您更改模型类以允许可为空的int。
然后,在种子方法中,针对dbcontext创建一个简单方法,以使用默认值更新新列,因为数据注释中的[DefaultValue]属性不会修改您的数据。
添加 - 迁移/更新 - 数据库以创建列和约束。
接下来,如果您希望允许非可空int,并假设您已将所有行更改为外键的某个有效值,请再次修改模型,Add-Migration / Update-database。
这为您的模型迁移提供了一个完整的链。稍后当您发布到实际站点时会派上用场,因为您的数据模型更改流程将保持不变。
- 希望这可以帮助。
此错误告诉您正在违反外键约束。要解决你有一些解决方案
存在于
你自己。
出现此问题是因为您的表不为空。
所以你要添加新字段而不像外键那样附加它。
public int? MedicalGroupId {get;组;在包管理控制台中执行update-database命令。
然后使用正确的数据填充此表(客户端)中的字段(值存在于MedicalGroupsId中)。
插入该行以创建外键
[ForeignKey的("MedicalGroupId")]
public virtual MedicalGroups MedicalGroup {get {return _MedicalGroup; } set {_MedicalGroup = value; }。
最后执行update-database命令。一切都会安好的。
对于可能在此处着陆的其他人,如果您使用的是Code-First Entity Framework并且只是尝试向具有现有数据的表添加新的必需列,则可能会有一个非常简单的修复。
注意:在执行此操作之前,只需知道您需要为所有现有行的新列添加有效值。考虑在继续之前您将添加到现有行的值。您可能希望为所需的查找表提供指示"无效"或"未知"的值。
在您的模型中,通过添加?将列设置为可为空?在int之后。保存并编译模型。运行Update-Database。
例:
1 2 | [ForeignKey("Title")] public int? TitleId { get; set; } |
在db中,通过将NULL值替换为有效的查找值来更新表。在我的情况下,我在标题查找表中添加了"未知",然后批量编辑所有行以引用该查找ID。
回到您的模型中,删除'?'所以该列不再可以为空。保存并编译模型,然后运行Update-Database
你现在应该好好去。
我有这个问题以及defaultValue设置,给出:
"该对象依赖于列ALTER TABLE ALTER COLUMN失败,因为一个或多个对象访问此列"。
结束将AddForeignKey / DropForeignKey移动到新的迁移并在单独的update-database命令中运行它们(不要在一个命令中执行这两个迁移,然后它就失败了。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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"); } |
我得到了问题的解决方案。问题是我在客户表中的"数据"。因为我的客户端表具有实际上不存在的medicalgroupid值,这就是为什么它给我外键约束的错误。
1 | Update Client set MedicalGroupId = NULL |
假设您的迁移顺序正确,即在引用之前将创建与外键关联的表。请遵循以下步骤:
我也收到了这条消息。问题是db中的测试数据不正确。
我在测试时没有验证,因此我对不允许空值的字段的ID有空值。修复数据后,update-database命令成功运行。
如果您在子表中有孤立记录,也会发生此错误。清理数据库应解决问题。
在程序包管理器控制台中运行Add-Migration InitialCreate -IgnoreChanges命令。这将创建一个空迁移,将当前模型作为快照。
在程序包管理器控制台中运行Update-Database命令。这将将InitialCreate迁移应用于数据库。由于实际迁移不包含任何更改,因此只需向__MigrationsHistory表添加一行,指示已应用此迁移。
您可以在此处获取更多详细信息:https://msdn.microsoft.com/en-us/library/dn579398(v = vs133).aspx