web-dev-qa-db-ja.com

データを失うことなくEntity Framework 5 Code First移行でデータベース列の名前を変更する方法は?

EF 5.0 Code First MigrationsでデフォルトのASP.NET MVC 4テンプレートが正常に実行されました。ただし、モデルプロパティ名を更新すると、対応するテーブルの列データはEF 5.0によって削除されます。

自動化された方法でデータを削除せずにテーブル列の名前を変更することはどういうわけですか?

68
Dante

移行のUpおよびDownメソッドを手動で編集して、RenameColumnメソッドを使用して、自動的に生成されるAddColumnおよびDropColumnを置き換えます。

106
Josh Gallagher

既に述べたように 、自動的に生成されるAddColumnDropColumnRenameColumnに置き換えます。

例:

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

canこれを行うと、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属性を削除できます。

11
Jess

今、この答えはEF4.3の私の知識に基づいているので、移行がEF5でほぼ同じように機能することを願っています:)移行を作成した後、UpメソッドとDownメソッドの間にコードを追加できるはずです古いプロパティの削除と新しいプロパティの作成。このコードは、プロパティデータを正しい方向に移動する必要があります。生のSQLを入力してデータの移動を実行できるSQL()メソッドで解決しました。

移行のUpメソッドで:

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

そして、Down()メソッドで:

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

このアプローチの欠点は、コードを現時点で作業しているデータベースと組み合わせる可能性があることです(DB固有の生のSQLを作成しているため)。データの移動にも他の方法が利用できる場合があります。

詳細情報はこちら: [〜#〜] msdn [〜#〜]

4
Daniel Persson

ジョシュ・ギャラガーの答えに追加:

一部の場所では、sp_RENAME構文は次のように記述されています。

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

ただし、実際には新しい列名に角括弧が含まれます。

DbMigrationのRenameColumn()メソッドはおそらく同じことを行うため、新しい列名を指定するときに角括弧を使用しないでください。

また、名前が変更される列が主キーの一部である場合、Up()およびDown()の自動生成コマンドにはDropPrimaryKey()およびAddPrimaryKey()が含まれます。 RenameColumn()を使用する場合、これらは必要ありません。基礎となるsp_RENAMEは、必要に応じて主キーを自動的に更新します。

3
jk7

コードファースト移行で列の名前を変更する2つのステップがあります

  1. 最初のステップでは、変更する列の上にColumnAttributeを追加してから、update-databaseコマンド

[列(「コンテンツ」)]
public string Description {set;取得する; }

  1. 2番目のステップ、

    • 部分クラスDbMigrationを作成するには、add-migration yournamechangeコマンドを使用します。

    • ここで上下メソッドに追加します

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を介して通信するためです。

3
Thảo Frederic

+ Josh Gallagherが言ったように、次のようなことをするためにup()を使用できます。

public override void Up()
        {

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

        }

私は this が移行を始めるのに役立つとわかりました;)

0
womd