Entity Framework 更改密钥类型
Entity Framework change Key Type
我创建了一个具有各种值的模型,但愚蠢地使用 GUID
作为我的密钥,我目前正试图将其更改为 Int
,但这样做时出现错误。
我有 运行 启用迁移命令:
Enable-Migrations -Force -ContextTypeName project.Models.MyContext
这创建了我期望的迁移但是当我 运行:
Update-Database -Force
我得到的错误是:
Operand type clash: uniqueidentifier is incompatible with int
我不关心数据库中当前包含的数据,因为它刚刚使用 SQL Server Express 数据库,但我更愿意找到一种方法来迁移它,而不是仅仅拥有完全放弃数据库,最好的方法是什么?
我已经得到了
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
在 Global.asax
.
我希望生成的迁移使用 AlterColumn 尝试将字段类型从 guid 更改为 int。这是不可能的,所以你需要自己修改生成的迁移:
假设你的 table 是 dbo.People 并且密钥称为 Id,你现在可能有这个:
DropPrimaryKey("dbo.People");
AlterColumn("dbo.People", "Id", c => c.Int(nullable: false, identity: true));
AddPrimaryKey("dbo.People", "Id");
改为:
DropPrimaryKey("dbo.People");
DropColumn("dbo.People", "Id");
AddColumn("dbo.People", "Id", c => c.Int(nullable: false, identity: true));
AddPrimaryKey("dbo.People", "Id");
请注意,如果您在其他地方引用了此密钥,则如果您有任何数据,则此技术将不起作用,因为所有密钥都将重新生成。
EF Core 生成的迁移的更新:
dotnet : System.Data.SqlClient.SqlException: Operand type clash: int is incompatible with uniqueidentifier
改变
migrationBuilder.AlterColumn<Guid>(
name: "VATID",
schema: "catalogue",
table: "Products",
nullable: false,
oldClrType: typeof(int));
进入
migrationBuilder.DropColumn(
name: "VATID",
schema: "catalogue",
table: "Products");
migrationBuilder.AddColumn<Guid>(
name: "VATID",
schema: "catalogue",
table: "Products",
nullable: false);
当然,这会破坏特定列的数据。但是他们显然不能转换成GUID。
我正在尝试向所选答案添加一些内容,因为我没有足够的声誉在此处添加评论:
还请添加代码以删除并重新创建索引,如果它无法删除列。例如
DropPrimaryKey("dbo.People");
DropIndex("IX_...") // If exists before
DropColumn("dbo.People", "Id");
AddColumn("dbo.People", "Id", c => c.Int(nullable: false,
identity: true));
AddPrimaryKey("dbo.People", "Id");
CreateIndex("IX_...", unique:(true/false)) // If existed before
AlterColumn 将删除和添加键(主键、外键等)但不会触及索引。我遇到过这个。
我创建了一个具有各种值的模型,但愚蠢地使用 GUID
作为我的密钥,我目前正试图将其更改为 Int
,但这样做时出现错误。
我有 运行 启用迁移命令:
Enable-Migrations -Force -ContextTypeName project.Models.MyContext
这创建了我期望的迁移但是当我 运行:
Update-Database -Force
我得到的错误是:
Operand type clash: uniqueidentifier is incompatible with int
我不关心数据库中当前包含的数据,因为它刚刚使用 SQL Server Express 数据库,但我更愿意找到一种方法来迁移它,而不是仅仅拥有完全放弃数据库,最好的方法是什么?
我已经得到了
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
在 Global.asax
.
我希望生成的迁移使用 AlterColumn 尝试将字段类型从 guid 更改为 int。这是不可能的,所以你需要自己修改生成的迁移:
假设你的 table 是 dbo.People 并且密钥称为 Id,你现在可能有这个:
DropPrimaryKey("dbo.People");
AlterColumn("dbo.People", "Id", c => c.Int(nullable: false, identity: true));
AddPrimaryKey("dbo.People", "Id");
改为:
DropPrimaryKey("dbo.People");
DropColumn("dbo.People", "Id");
AddColumn("dbo.People", "Id", c => c.Int(nullable: false, identity: true));
AddPrimaryKey("dbo.People", "Id");
请注意,如果您在其他地方引用了此密钥,则如果您有任何数据,则此技术将不起作用,因为所有密钥都将重新生成。
EF Core 生成的迁移的更新:
dotnet : System.Data.SqlClient.SqlException: Operand type clash: int is incompatible with uniqueidentifier
改变
migrationBuilder.AlterColumn<Guid>(
name: "VATID",
schema: "catalogue",
table: "Products",
nullable: false,
oldClrType: typeof(int));
进入
migrationBuilder.DropColumn(
name: "VATID",
schema: "catalogue",
table: "Products");
migrationBuilder.AddColumn<Guid>(
name: "VATID",
schema: "catalogue",
table: "Products",
nullable: false);
当然,这会破坏特定列的数据。但是他们显然不能转换成GUID。
我正在尝试向所选答案添加一些内容,因为我没有足够的声誉在此处添加评论: 还请添加代码以删除并重新创建索引,如果它无法删除列。例如
DropPrimaryKey("dbo.People");
DropIndex("IX_...") // If exists before
DropColumn("dbo.People", "Id");
AddColumn("dbo.People", "Id", c => c.Int(nullable: false,
identity: true));
AddPrimaryKey("dbo.People", "Id");
CreateIndex("IX_...", unique:(true/false)) // If existed before
AlterColumn 将删除和添加键(主键、外键等)但不会触及索引。我遇到过这个。