繁体   English   中英

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

[英]How to rename a database column in Entity Framework 5 Code First migrations without losing data?

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

是否可以在不以自动方式删除数据的情况下重命名表列?

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

如前所述,用DropColumn替换自动生成的AddColumnRenameColumn

例子:

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

如果您希望您的属性和 DB 列具有相同的名称,您可以稍后重命名该属性并删除Column属性。

您有 2 个步骤来重命名代码第一次迁移中的列

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

[列(“内容”)]
公共字符串 描述 { set; 得到; }

  1. 第二步,

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

    • 在这里添加上下方法

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 进行通信。

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

在迁移的 Up 方法中:

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

在 Down() 方法中:

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

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

此处提供更多信息: MSDN

添加乔什加拉格尔的回答:

在某些地方,sp_RENAME 语法是这样描述的:

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

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

DbMigration 的 RenameColumn() 方法可能会执行相同的操作,因此在指定新列名时避免使用方括号。

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

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

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

        }

我发现对开始迁移很有帮助;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM