Я переименовал пару сущностей и их свойства навигации и сгенерировал новую миграцию в EF 5. Как обычно с переименованием в миграциях EF, по умолчанию объект собирался отбрасывать объекты и воссоздавать их. Это не то, что я хотел, поэтому мне пришлось создать файл миграции с нуля.
public override void Up()
{
DropForeignKey("dbo.ReportSectionGroups", "Report_Id", "dbo.Reports");
DropForeignKey("dbo.ReportSections", "Group_Id", "dbo.ReportSectionGroups");
DropForeignKey("dbo.Editables", "Section_Id", "dbo.ReportSections");
DropIndex("dbo.ReportSectionGroups", new[] { "Report_Id" });
DropIndex("dbo.ReportSections", new[] { "Group_Id" });
DropIndex("dbo.Editables", new[] { "Section_Id" });
RenameTable("dbo.ReportSections", "dbo.ReportPages");
RenameTable("dbo.ReportSectionGroups", "dbo.ReportSections");
RenameColumn("dbo.ReportPages", "Group_Id", "Section_Id");
AddForeignKey("dbo.ReportSections", "Report_Id", "dbo.Reports", "Id");
AddForeignKey("dbo.ReportPages", "Section_Id", "dbo.ReportSections", "Id");
AddForeignKey("dbo.Editables", "Page_Id", "dbo.ReportPages", "Id");
CreateIndex("dbo.ReportSections", "Report_Id");
CreateIndex("dbo.ReportPages", "Section_Id");
CreateIndex("dbo.Editables", "Page_Id");
}
public override void Down()
{
DropIndex("dbo.Editables", "Page_Id");
DropIndex("dbo.ReportPages", "Section_Id");
DropIndex("dbo.ReportSections", "Report_Id");
DropForeignKey("dbo.Editables", "Page_Id", "dbo.ReportPages");
DropForeignKey("dbo.ReportPages", "Section_Id", "dbo.ReportSections");
DropForeignKey("dbo.ReportSections", "Report_Id", "dbo.Reports");
RenameColumn("dbo.ReportPages", "Section_Id", "Group_Id");
RenameTable("dbo.ReportSections", "dbo.ReportSectionGroups");
RenameTable("dbo.ReportPages", "dbo.ReportSections");
CreateIndex("dbo.Editables", "Section_Id");
CreateIndex("dbo.ReportSections", "Group_Id");
CreateIndex("dbo.ReportSectionGroups", "Report_Id");
AddForeignKey("dbo.Editables", "Section_Id", "dbo.ReportSections", "Id");
AddForeignKey("dbo.ReportSections", "Group_Id", "dbo.ReportSectionGroups", "Id");
AddForeignKey("dbo.ReportSectionGroups", "Report_Id", "dbo.Reports", "Id");
}
Все, что я пытаюсь сделать, это переименовать dbo.ReportSections
в, dbo.ReportPages
а затем dbo.ReportSectionGroups
в dbo.ReportSections
. Затем мне нужно переименовать столбец внешнего ключа dbo.ReportPages
с Group_Id
в Section_Id
.
Я удаляю внешние ключи и индексы, связывающие таблицы вместе, затем переименовываю таблицы и столбец внешнего ключа, затем снова добавляю индексы и внешние ключи. Я предполагал, что это сработает, но получаю ошибку SQL.
Msg 15248, уровень 11, состояние 1, процедура sp_rename, строка 215 Либо параметр @objname неоднозначен, либо заявленный @objtype (COLUMN) неверен. Msg 4902, уровень 16, состояние 1, строка 10 Не удается найти объект «dbo.ReportSections», поскольку он не существует или у вас нет разрешений.
Мне нелегко понять, что здесь не так. Любое понимание было бы чрезвычайно полезно.
Ответы:
Неважно. Я делал этот путь более сложным, чем нужно было на самом деле.
Это все, что мне было нужно. Методы переименования просто генерируют вызов системной хранимой процедуры sp_rename , и я предполагаю, что это позаботилось обо всем, включая внешние ключи с новым именем столбца.
источник
RenameColumn
генерирует операторsp_rename
T-SQL, который используетparsename
внутреннее использование, что имеет некоторые ограничения. Поэтому, если у вас есть имя таблицы, в котором есть точки, например "SubSystemA.Tablename", используйте:RenameColumn("dbo.[SubSystemA.Tablename]", "OldColumnName", "NewColumnName");
RenameIndex(..)
при миграции, чтобы переименоватьRenameTable(..)
для переименования FK и PK. Звучит неправильно, но у меня это сработало. Это метод, который создает правильный T-SQL (execute sp_rename ...
). Если вы выполните update-database -verbose, вы убедитесь в этом сами.Если вам не нравится писать / изменять требуемый код в классе Migration вручную, вы можете использовать двухэтапный подход, который автоматически создает
RenameColumn
требуемый код:Шаг 1. Используйте,
ColumnAttribute
чтобы ввести имя нового столбца, а затем добавьте миграцию (напримерAdd-Migration ColumnChanged
)Шаг второй: измените имя свойства и снова примените его к той же миграции (например,
Add-Migration ColumnChanged -force
) в консоли диспетчера пакетов.Если вы посмотрите на класс Migration, вы увидите, что автоматически сгенерированный код
RenameColumn
.источник
The name 'Rename_SalesArea' is used by an existing migration.
-force
параметр при использовании добавления-миграцииЧтобы немного расширить ответ Хосейна Наримани Рэда, вы можете переименовать как таблицу, так и столбцы, используя System.ComponentModel.DataAnnotations.Schema.TableAttribute и System.ComponentModel.DataAnnotations.Schema.ColumnAttribute соответственно.
У этого есть пара преимуществ:
Например, добавив
[Table("Staffs")]
:Сгенерирует миграцию:
источник
В EF Core я использую следующие операторы для переименования таблиц и столбцов:
Что касается переименования таблиц:
Что касается переименования столбцов:
источник
В ef core вы можете изменить миграцию, созданную после добавления миграции. А потом сделайте update-database. Образец приведен ниже:
источник
Я просто пробовал то же самое в EF6 (переименование первого объекта кода). Я просто переименовал класс и добавил миграцию с помощью консоли диспетчера пакетов и вуаля, миграция с использованием RenameTable (...) была автоматически сгенерирована для меня. Я должен признать, что я убедился, что единственным изменением объекта было его переименование, чтобы не было новых столбцов или переименованных столбцов, поэтому я не могу быть уверен, относится ли это к EF6 или просто EF (всегда) мог обнаруживать такие простые миграции.
источник
DbSet
в вашейDatabaseContext
). Изменение первичного ключа действительно вызывает проблемы. Миграция попытается удалить его и создать новый. Поэтому вам нужно отрегулировать это и сделать так, как ответил Чев, переименовать столбец.Имена таблиц и столбцов могут быть указаны как часть сопоставления
DbContext
. Тогда в миграциях этого делать не нужно.источник