我成功地使用EF 5.0 Code First Migrations运行了默认的ASP.NET MVC 4模板。然而,当我更新一个模型属性名称时,对应的表列数据会被EF 5.0删除。
有没有一种自动化的方式可以重命名表列而不丢失数据?
我成功地使用EF 5.0 Code First Migrations运行了默认的ASP.NET MVC 4模板。然而,当我更新一个模型属性名称时,对应的表列数据会被EF 5.0删除。
有没有一种自动化的方式可以重命名表列而不丢失数据?
手动编辑迁移的Up
和Down
方法,使用RenameColumn
方法替换自动生成的AddColumn
和DropColumn
。
正如已经提到的,请用RenameColumn
替换自动生成的 AddColumn
和 DropColumn
。
例如:
namespace MyProject.Model.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class RenameMyColumn : DbMigration
{
public override void Up()
{
// Remove the following auto-generated lines
AddColumn("dbo.MyTable", "NewColumn", c => c.String(nullable: false, maxLength: 50));
DropColumn("dbo.MyTable", "OldColumn");
// Add this line
RenameColumn("dbo.MyTable", "OldColumn", "NewColumn");
}
public override void Down()
{
// Remove the following auto-generated lines
AddColumn("dbo.MyTable", "OldColumn", c => c.String(nullable: false, maxLength: 50));
DropColumn("dbo.MyTable", "NewColumn");
// Add this line
RenameColumn("dbo.MyTable", "NewColumn", "OldColumn");
}
}
}
如果您这样做,您可以让迁移为您调用RenameColumn
:
[Column("NewName")]
public string OldName { get; set; }
这是生成的迁移文件:
public override void Up()
{
RenameColumn(table: "Schema.MyTable", name: "OldName", newName: "NewName");
}
public override void Down()
{
RenameColumn(table: "Schema.MyTable", name: "NewName", newName: "OldName");
}
如果您想让属性和数据库列具有相同的名称,则可以稍后重命名属性并删除Column
特性。Update-Database -Script
。然后,您可以随时运行 SQL sp_rename
命令。 :D - Jess在Code First Migration中重命名列有两个步骤:
[Column("Content")]
public string Description { set; get; }
第二步,
运行add-migration yournamechange命令以创建一个DbMigration局部类。
将RenameColumn("yourDatabase","name","newName")方法添加到up和down方法中。
RenameColumn("yourDatabase","name","newName");
public override void Up()
{
RenameColumn("dbo.your_database", "oldColumn",
"newColumn");
}
public override void Down()
{
RenameColumn("dbo.your_database", "newColumn",
"oldColumn");
}
当您连接时,您的数据库和模型类将通过数据库中的name_column和模型中属性方法中的name_type进行通信。
SQL("update [TheTable] set [NewColumn] = [OldColumn]");
在Down()方法中:
SQL("update [TheTable] set [OldColumn] = [NewColumn]");
补充Josh Gallagher的回答:
在某些地方,sp_RENAME语法被描述为:
sp_RENAME 'TableName.[OldColumnName]' , '[NewColumnName]', 'COLUMN'
然而,这实际上会在新列名中包含括号。
DbMigration的RenameColumn()方法可能会做同样的事情,因此在指定新列名时要避免使用括号。
此外,在Up()和Down()中自动生成的命令包括DropPrimaryKey()和AddPrimaryKey(),如果被重命名的列是主键的一部分,则不需要进行这些操作。使用RenameColumn()时,底层的sp_RENAME会自动更新主键(如果需要的话)。
migrationBuilder.RenameColumn(
name: "oldname",
table: "tablename",
newName: "newname",
schema: "schema");
就像Josh Gallagher所说的那样,您可以使用up()来执行以下操作:
public override void Up()
{
RenameColumn("dbo.atable","oldname","newname");
AddColumn("dbo.anothertable", "columname", c => c.String(maxLength: 250));
}
我发现this对于入门迁移非常有帮助;)
RenameColumn
生成一个sp_rename
的 T-SQL 语句,它在内部使用了parsename
函数,该函数有一些限制。因此,如果你的表名中带有点号,例如 "SubSystemA.Tablename",那么请使用:RenameColumn("dbo.[SubSystemA.Tablename]", "OldColumnName", "NewColumnName");
。 - IlanAutomaticMigration = true
。然后,执行命令Add-Migration renameColumnXXX
。之后检查生成的迁移文件并删除DropColumn
和AddColumn
。 - RasikaSammigrationBuilder.RenameColumn(name: "oldname",table: "tablename",newName: "newname",schema: "schema");
https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.migrations.migrationbuilder.renamecolumn?view=efcore-5.0 - Chamika Sandamal