Как переименовать столбец базы данных в миграциях Entity Framework 5 Code First без потери данных?

Я получил шаблон ASP.NET MVC 4 по умолчанию, успешно работающий с EF 5.0 Code First Migrations. Однако, когда я обновляю имя свойства модели, соответствующие данные столбца таблицы удаляются EF 5.0.

Можно ли как-то переименовать столбец таблицы, не удаляя данные автоматически?


person Dante    schedule 27.10.2012    source источник


Ответы (8)


Вручную отредактируйте методы Up и Down миграции, чтобы использовать метод RenameColumn для замены AddColumn и DropColumn, которые он автоматически генерирует для вас.

person Josh Gallagher    schedule 29.11.2012
comment
Будьте осторожны с именами таблиц, в которых есть точки. RenameColumn генерирует оператор sp_rename T-SQL, который использует parsename для внутреннего использования, что имеет некоторые ограничения. Итак, если у вас есть имя таблицы, в котором есть точки, например. SubSystemA.Tablename затем используйте: RenameColumn("dbo.[SubSystemA.Tablename]", "OldColumnName", "NewColumnName"); - person Ilan; 16.05.2013
comment
Я думаю, что этот ответ предполагает, что у вас есть AutomaticMigration = true Затем вы выполняете команду Add-Migration renameColumnXXX . После этого проверьте сгенерированный файл миграции и удалите DropColumn и AddColum. - person JenonD; 04.11.2020
comment
Для ядра EF вы можете использовать следующее: migrationBuilder.RenameColumn(name: "oldname",table: "tablename",newName: "newname",schema: "schema"); docs.microsoft.com/en-us/dotnet/api/ - person Chamika Sandamal; 23.03.2021

Как уже было сказано, замените автоматически созданные AddColumn и DropColumn на RenameColumn.

Пример:

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");
        }
    }
}
person Zanon    schedule 23.12.2015

Вы можете заставить миграцию вызывать 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.

person Jess    schedule 19.01.2017
comment
И просто чтобы добавить еще один полезный совет, вы также можете запустить это в консоли диспетчера пакетов: Update-Database -Script. Затем вы можете запустить команду SQL sp_rename на досуге. :D - person Jess; 19.01.2017
comment
Предпочтительный подход, поскольку также рассматривается имя свойства модели. И я проверил, что на необязательном втором шаге переименования свойства создается пустая миграция. - person bvj; 05.03.2020

Теперь этот ответ основан на моем знании EF4.3, поэтому я надеюсь, что миграции работают примерно так же в EF5:) После того, как вы создали миграцию, вы сможете добавить код в методы Up и Down, между отбрасывание старой собственности и создание новой собственности. Этот код должен перемещать данные свойств в правильном направлении. Я решил это с помощью метода SQL(), в котором вы можете ввести необработанный SQL для выполнения перемещения данных.

В методе Up миграции:

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

и в методе Down():

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

Недостатком этого подхода является то, что вы можете связать свой код с базой данных, с которой вы работаете в данный момент (поскольку вы пишете необработанный SQL для конкретной БД). Также могут быть доступны другие методы перемещения данных.

Дополнительные сведения доступны здесь: MSDN.

person Daniel Persson    schedule 27.10.2012

у вас есть 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 в методе свойства в модели выше.

person Thảo Frederic    schedule 17.07.2017

Добавление к ответу Джоша Галлахера:

В некоторых местах синтаксис sp_RENAME описывается так:

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

Однако на самом деле это будет включать скобки в новое имя столбца.

Метод RenameColumn() в DbMigration, вероятно, сделает то же самое, поэтому избегайте использования квадратных скобок при указании имени нового столбца.

Кроме того, автоматически сгенерированные команды в Up() и Down() включают DropPrimaryKey() и AddPrimaryKey(), если переименовываемый столбец является частью первичного ключа. Они не нужны при использовании RenameColumn(). Базовая процедура sp_RENAME автоматически обновляет первичный ключ, если это необходимо.

person jk7    schedule 25.03.2015

В Entity Framework Core 3.1.1, если вам нужно переименовать столбец, добавьте миграцию, как показано ниже.

migrationBuilder.RenameColumn(
                                name: "oldname",
                                table: "tablename",
                                newName: "newname",
                                schema: "schema");
person Ishika Jain    schedule 14.07.2020

как сказал +Джош Галлахер, вы можете использовать up() для таких вещей, как:

public override void Up()
        {

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

        }

я нашел это хорошая помощь в переходе к миграции ;)

person womd    schedule 29.08.2015