如何在Entity Framework 5 Code First迁移中重命名数据库列而不丢失数据?

时间:2012-10-27 22:05:58

标签: c# .net entity-framework entity-framework-5

我使用EF 5.0 Code First Migrations成功运行了默认的ASP.NET MVC 4模板。但是,当我更新模型属性名称时,EF 5.0将删除相应的表列数据。

是否有可能以不自动的方式重命名表列而不丢弃数据?

8 个答案:

答案 0 :(得分:103)

手动编辑迁移的Up和Down方法,以使用RenameColumn方法替换为您自动生成的AddColumnDropColumn

答案 1 :(得分:37)

As already said,替换AddColumn自动生成的DropColumnRenameColumn

示例:

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");
        }
    }
}

答案 2 :(得分:11)

如果您执行此操作, 可以为您迁移以致电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属性。

答案 3 :(得分:4)

现在,这个答案基于我对EF4.3的了解,所以我希望迁移在EF5中大致相同:)创建迁移后,您应该能够在Up和Down中添加代码在删除旧属性和创建新属性之间的方法。此代码应以正确的方向移动属性数据。我已经使用SQL()方法解决了这个问题,您可以在其中输入原始SQL来执行数据移动。

在迁移的Up方法中:

SQL("update [TheTable] set [NewColumn] = [OldColumn]");

并在Down()方法中:

SQL("update [TheTable] set [OldColumn] = [NewColumn]");

这种方法的缺点是你可能会将你的代码与你正在使用的数据库结合起来(因为你正在编写原始的特定于数据库的SQL)。可能还有其他方法可用于数据移动。

此处提供了更多信息:MSDN

答案 4 :(得分:3)

加入Josh Gallagher的回答:

在某些地方,sp_RENAME语法描述如下:

sp_RENAME 'TableName.[OldColumnName]' , '[NewColumnName]', 'COLUMN'

但是,这实际上会包含新列名称中的括号。

DbMigration的RenameColumn()方法可能也会这样做,因此在指定新列名时请避免使用括号。

此外,Up()&中的自动生成命令如果重命名的列是主键的一部分,则Down()包括DropPrimaryKey()和AddPrimaryKey()。使用RenameColumn()时不需要这些。如果需要,底层sp_RENAME会自动更新主键。

答案 5 :(得分:2)

您有2个步骤在代码首次迁移中重命名列

  1. 第一步,在列上方添加ColumnAttribute,进行更改,然后使用update-database命令
  2.   

    [柱("内容&#34)]
      public string说明{set;得到; }

    1. 第二步,

      • add-migration yournamechange命令以创建部分类DbMigration。

      • 在此处添加上下方法

    2. RenameColumn(" yourDatabase""名称""&了newName#34);

      public override void Up()
        {
              RenameColumn("dbo.your_database", "oldColumn",          
             "newColumn");
        }
      
      
      public override void Down()
        {
              RenameColumn("dbo.your_database", "newColumn", 
              "oldColumn");
        }
      

      因为当你连接时,你的数据库和模型类将通过数据库中的name_column和上面模型中属性方法的name_type进行通信。

答案 6 :(得分:2)

Entity Framework Core 3.1.1 中,如果您需要重命名列- 如下添加迁移

migrationBuilder.RenameColumn(
                                name: "oldname",
                                table: "tablename",
                                newName: "newname",
                                schema: "schema");

答案 7 :(得分:0)

<+>喜欢+ Josh Gallagher说,你可以使用up()来做类似的事情:

public override void Up()
        {

            RenameColumn("dbo.atable","odlanem","newname");
            AddColumn("dbo.anothertable", "columname", c => c.String(maxLength: 250));

        }

我发现this在开始迁移方面提供了很好的帮助;)