Миграции Entity Framework переименование таблиц и столбцов
я переименовал пару объектов и их свойства навигации и сгенерировал новую миграцию в 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 to dbo.ReportPages а то dbo.ReportSectionGroups до dbo.ReportSections. Затем мне нужно переименовать столбец внешнего ключа на dbo.ReportPages С Group_Id to Section_Id.
я отбрасываю внешние ключи и индексы, связывающие таблицы вместе, затем я переименовываю таблицы и столбец внешнего ключа, а затем снова добавляю индексы и внешние ключи. Я предполагал, что это будет работать, но я получаю ошибку SQL.
Msg 15248, Уровень 11, состояние 1, процедура sp_rename, строка 215
Либо параметр @objname неоднозначен, либо заявленный @objtype (столбец) неверен.
Msg 4902, Уровень 16, Состояние 1, Линия 10
Не может найдите объект " dbo.ReportSections", потому что он не существует или у вас нет разрешений.
мне нелегко понять, что здесь не так. Любое понимание было бы чрезвычайно полезно.
6 ответов:
Фигу. Я делал этот путь более сложным, чем это действительно должно было быть.
Это было все, что мне нужно. Методы переименования просто генерируют вызов процедура sp_rename системная хранимая процедура, и я думаю, что позаботился обо всем, включая внешние ключи с новым именем столбца.
public override void Up() { RenameTable("ReportSections", "ReportPages"); RenameTable("ReportSectionGroups", "ReportSections"); RenameColumn("ReportPages", "Group_Id", "Section_Id"); } public override void Down() { RenameColumn("ReportPages", "Section_Id", "Group_Id"); RenameTable("ReportSections", "ReportSectionGroups"); RenameTable("ReportPages", "ReportSections"); }
Если вам не нравится писать/изменять необходимый код в классе миграции вручную, вы можете следовать двухэтапному подходу, который автоматически делает
RenameColumnкод, который требуется:Шаг Первый использовать
ColumnAttributeчтобы ввести новое имя столбца, а затем добавить миграцию (например,Add-Migration ColumnChanged)public class ReportPages { [Column("Section_Id")] //Section_Id public int Group_Id{get;set} }Шаг-Два изменить имя свойства и снова обратиться к той же миграции (например,
Add-Migration ColumnChanged) в менеджере пакетов Консольpublic class ReportPages { [Column("Section_Id")] //Section_Id public int Section_Id{get;set} }если вы посмотрите на класс миграции вы можете увидеть автоматически генерируемый код
RenameColumn.
чтобы немного расширить ответ Хоссейна Наримани рад, вы можете переименовать как таблицу, так и столбцы с помощью System.ComponentModel.DataAnnotations.Схема.TableAttribute и System.ComponentModel.DataAnnotations.Схема.ColumnAttribute соответственно.
Это имеет несколько преимуществ:
- это не только автоматически создаст миграцию имен, но и
- он также будет восхитительно удалять любые внешние ключи и воссоздавать их против новой таблицы и имена столбцов, дающие внешние ключи и константы имен собственных.
- все это без потери данных в таблице
например, при добавлении
[Table("Staffs")]:[Table("Staffs")] public class AccountUser { public long Id { get; set; } public long AccountId { get; set; } public string ApplicationUserId { get; set; } public virtual Account Account { get; set; } public virtual ApplicationUser User { get; set; } }будет генерировать миграции:
protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.DropForeignKey( name: "FK_AccountUsers_Accounts_AccountId", table: "AccountUsers"); migrationBuilder.DropForeignKey( name: "FK_AccountUsers_AspNetUsers_ApplicationUserId", table: "AccountUsers"); migrationBuilder.DropPrimaryKey( name: "PK_AccountUsers", table: "AccountUsers"); migrationBuilder.RenameTable( name: "AccountUsers", newName: "Staffs"); migrationBuilder.RenameIndex( name: "IX_AccountUsers_ApplicationUserId", table: "Staffs", newName: "IX_Staffs_ApplicationUserId"); migrationBuilder.RenameIndex( name: "IX_AccountUsers_AccountId", table: "Staffs", newName: "IX_Staffs_AccountId"); migrationBuilder.AddPrimaryKey( name: "PK_Staffs", table: "Staffs", column: "Id"); migrationBuilder.AddForeignKey( name: "FK_Staffs_Accounts_AccountId", table: "Staffs", column: "AccountId", principalTable: "Accounts", principalColumn: "Id", onDelete: ReferentialAction.Cascade); migrationBuilder.AddForeignKey( name: "FK_Staffs_AspNetUsers_ApplicationUserId", table: "Staffs", column: "ApplicationUserId", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Restrict); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropForeignKey( name: "FK_Staffs_Accounts_AccountId", table: "Staffs"); migrationBuilder.DropForeignKey( name: "FK_Staffs_AspNetUsers_ApplicationUserId", table: "Staffs"); migrationBuilder.DropPrimaryKey( name: "PK_Staffs", table: "Staffs"); migrationBuilder.RenameTable( name: "Staffs", newName: "AccountUsers"); migrationBuilder.RenameIndex( name: "IX_Staffs_ApplicationUserId", table: "AccountUsers", newName: "IX_AccountUsers_ApplicationUserId"); migrationBuilder.RenameIndex( name: "IX_Staffs_AccountId", table: "AccountUsers", newName: "IX_AccountUsers_AccountId"); migrationBuilder.AddPrimaryKey( name: "PK_AccountUsers", table: "AccountUsers", column: "Id"); migrationBuilder.AddForeignKey( name: "FK_AccountUsers_Accounts_AccountId", table: "AccountUsers", column: "AccountId", principalTable: "Accounts", principalColumn: "Id", onDelete: ReferentialAction.Cascade); migrationBuilder.AddForeignKey( name: "FK_AccountUsers_AspNetUsers_ApplicationUserId", table: "AccountUsers", column: "ApplicationUserId", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Restrict); }
в EF Core (2.0) я использую следующие инструкции для переименования таблиц и столбцов:
что касается переименования таблиц:
protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.RenameTable(name: "OldTableName", schema: "dbo", newName: "NewTableName", newSchema: "dbo"); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.RenameTable(name: "NewTableName", schema: "dbo", newName: "OldTableName", newSchema: "dbo"); }что касается переименования столбцов:
protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.RenameColumn(name: "OldColumnName", table: "TableName", newName: "NewColumnName", schema: "dbo"); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.RenameColumn(name: "NewColumnName", table: "TableName", newName: "OldColumnName", schema: "dbo"); }
Я только что попробовал то же самое в EF6 (Code first entity rename). Я просто переименовал класс и добавил миграцию с помощью консоли диспетчера пакетов и вуаля, миграцию с использованием RenameTable(...) был автоматически сгенерирован для меня. Я должен признать, что я убедился, что единственное изменение в сущности было переименование его, поэтому никаких новых столбцов или переименованных столбцов, поэтому я не могу быть уверен, что это EF6 вещь или просто что EF был (всегда) в состоянии обнаружить такие простые миграции.
имена таблиц и столбцов могут быть указаны как часть отображения
DbContext. Тогда нет необходимости делать это в миграции.public class MyContext : DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Restaurant>() .HasMany(p => p.Cuisines) .WithMany(r => r.Restaurants) .Map(mc => { mc.MapLeftKey("RestaurantId"); mc.MapRightKey("CuisineId"); mc.ToTable("RestaurantCuisines"); }); } }
Comments