当我尝试将列类型从 datetime 更改为smallint 时,EF Core 更新数据库失败:“操作数类型冲突:日期与smallint 不兼容”
迁移文件:
公共分部类 BookYearFieldChanged :迁移
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<short>(
name: "Published",
table: "Books",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "date");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTime>(
name: "Published",
table: "Books",
type: "date",
nullable: false,
oldClrType: typeof(short));
}
}
创建具有所需数据类型的新列,使用所需数据更新新列并删除上一列。
CREATE TABLE [dbo].[table1](
[columr1] [nvarchar](100) NULL,
[DTime] [datetime] NULL
)
/* you can't do like this*/
/* alter table table1
alter column Dtime smallint */
ALTER TABLE table1
ADD DTM smallint
UPDATE table1
SET DTM = CAST(DTime as smallint)
ALTER TABLE table1
DROP column DTime
sp_rename 'table1.DTM','DTime','column'
GO
基本上,EF 无法自动为您将类型从short 转换为datetime,并且无论如何进行这种转换都是没有意义的。您必须使用类似这样的内容手动调整迁移文件。
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Published",
table: "Books");
migrationBuilder.AddColumn<DateTime>(
name: "Published",
table: "Books",
nullable: false,
type: "datetime2");
}
本质上,这将删除现有列并将其替换为新列,而不是尝试进行转换。您还需要对 Down() 方法执行相同但相反的操作。
不幸的是,这会导致数据丢失,因此请确保在更新数据库之前备份数据,以便您可以在需要时将其加载回来。