实体框架更改 Id 类型

Posted

技术标签:

【中文标题】实体框架更改 Id 类型【英文标题】:Entity Framework change Id type 【发布时间】:2014-08-21 05:10:48 【问题描述】:

我已将 Id 属性的类型从 Int 更改为 Guid,没有其他实体引用该 Id,并且我已从数据库中手动删除该实体的所有记录,我生成的迁移类如下所示:

public override void Up()

    AlterColumn("dbo.RoutineExercises", "RoutineExerciseId", c => c.Guid(nullable: false));


public override void Down()

    AlterColumn("dbo.RoutineExercises", "RoutineExerciseId", c => c.Int(nullable: false, identity: true));

当我运行 update-database 命令时出现此错误:

对象“PK_dbo.RoutineExercises”依赖于列“RoutineExerciseId”。 ALTER TABLE ALTER COLUMN RoutineExerciseId 失败,因为一个或多个对象访问此列。

我的 FluentAPI 配置如下所示:

 modelBuilder.Entity<RoutineExercise>().HasKey(r => r.RoutineExerciseId);
 modelBuilder.Entity<RoutineExercise>()
                .HasRequired(r => r.Exercise)
                .WithMany()
                .HasForeignKey(r => r.ExerciseId)
                .WillCascadeOnDelete(true);

            modelBuilder.Entity<RoutineExercise>()
                .HasRequired(r => r.Routine)
                .WithMany()
                .HasForeignKey(r => r.RoutineId)
                .WillCascadeOnDelete(true);

如何在不删除整个数据库的情况下解决此问题?

【问题讨论】:

【参考方案1】:

您可以尝试分阶段进行迁移 - 我不确定,但您的流畅配置会导致根据您要更改的字段创建主键,并且迁移向导无法考虑需要删除主键,将字段转换为 guid,然后重建新的主键。

所以我的建议是逐步进行迁移: 1.从routineexerciseid中移除haskey并移动到另一个字段或者创建一个新的复合键——ef需要一个主键 2.移动主键后,您应该能够更改列 3. 最后恢复该列的主键。

或者 创建一个全新的列作为主键的 guid,删除旧列,然后根据需要重命名新列

【讨论】:

【参考方案2】:

我知道这是一个老问题,但如果其他人正在寻找这个答案,我自己就发现了。您需要在更改之前删除主键。

DropPrimaryKey("dbo.RoutineExercises",new[] "RoutineExerciseId");

【讨论】:

【参考方案3】:

进行迁移重置比更改很多内容并可能弄乱您的数据库更容易。不过,我确实建议您在继续此操作之前备份您的数据。

这里概述了该过程:

https://weblog.west-wind.com/posts/2016/jan/13/resetting-entity-framework-migrations-to-a-clean-slate

【讨论】:

以上是关于实体框架更改 Id 类型的主要内容,如果未能解决你的问题,请参考以下文章

实体框架更改列类型

AspNetUser 上的实体框架流利的 api 1:1 属性无法更改 Account_Id 属性

如何从实体框架 6 中的 Auditlog 实体获取 id

在 DbContext 中看不到实体框架数据库更改

无法使用实体框架保存数据库更改

如何更改实体框架为日期时间生成 SQL 精度的方式