Eu renomei duas entidades e suas propriedades de navegação e gerei uma nova Migração no EF 5. Como é usual com renomeações em migrações EF, por padrão ele iria descartar objetos e recriá-los. Não era isso que eu queria, então tive que criar o arquivo de migração do zero.
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");
}
Tudo o que estou tentando fazer é renomear dbo.ReportSections
para dbo.ReportPages
e depois dbo.ReportSectionGroups
para dbo.ReportSections
. Em seguida, preciso renomear a coluna de chave estrangeira dbo.ReportPages
de Group_Id
para Section_Id
.
Estou eliminando as chaves estrangeiras e os índices que vinculam as tabelas, depois renomeio as tabelas e a coluna da chave estrangeira e, em seguida, estou adicionando os índices e as chaves estrangeiras novamente. Achei que isso iria funcionar, mas estou recebendo um erro de SQL.
Msg 15248, nível 11, estado 1, procedimento sp_rename, linha 215 O parâmetro @objname é ambíguo ou o @objtype reivindicado (COLUMN) está incorreto. Msg 4902, Nível 16, Estado 1, Linha 10 Não é possível localizar o objeto "dbo.ReportSections" porque ele não existe ou você não tem permissões.
Não estou tendo um tempo fácil para descobrir o que está errado aqui. Qualquer insight seria extremamente útil.
Respostas:
Deixa pra lá. Eu estava tornando isso mais complicado do que realmente precisava ser.
Isso era tudo de que eu precisava. Os métodos rename apenas geram uma chamada para o procedimento armazenado do sistema sp_rename e acho que isso cuidou de tudo, incluindo as chaves estrangeiras com o novo nome da coluna.
fonte
RenameColumn
gera umasp_rename
instrução T-SQL que usa usaparsename
internamente que tem algumas limitações. Portanto, se você tiver um nome de tabela com pontos, por exemplo, "SubSystemA.Tablename", use:RenameColumn("dbo.[SubSystemA.Tablename]", "OldColumnName", "NewColumnName");
RenameIndex(..)
em sua migração para renomeá-loRenameTable(..)
para renomear os FKs e PKs . Não parece certo, mas é o que funcionou para mim. É o método que cria o T-SQL (execute sp_rename ...
) correto . Se você atualizar o banco de dados -verbose, verá por si mesmo.Se você não gosta de escrever / alterar o código necessário na classe Migration manualmente, você pode seguir uma abordagem de duas etapas que cria automaticamente o
RenameColumn
código que é necessário:Primeiro passo Use o
ColumnAttribute
para introduzir o novo nome da coluna e, em seguida, adicionar migração (por exemploAdd-Migration ColumnChanged
)Etapa dois altere o nome da propriedade e aplique novamente à mesma migração (por exemplo
Add-Migration ColumnChanged -force
) no console do gerenciador de pacotesSe você olhar para a classe Migration, poderá ver o código gerado automaticamente é
RenameColumn
.fonte
The name 'Rename_SalesArea' is used by an existing migration.
-force
parâmetro ao usar a migração de adiçãoPara expandir um pouco a resposta de Hossein Narimani Rad, você pode renomear uma tabela e colunas usando System.ComponentModel.DataAnnotations.Schema.TableAttribute e System.ComponentModel.DataAnnotations.Schema.ColumnAttribute respectivamente.
Isso tem alguns benefícios:
Por exemplo, adicionando
[Table("Staffs")]
:Irá gerar a migração:
fonte
No EF Core, eu uso as seguintes instruções para renomear tabelas e colunas:
Quanto à renomeação de tabelas:
Quanto à renomeação de colunas:
fonte
No ef core, você pode alterar a migração que foi criada após adicionar migração. E então atualize o banco de dados. Um exemplo é dado abaixo:
fonte
Acabei de tentar o mesmo no EF6 (renomear entidade de código primeiro). Simplesmente renomeei a classe e adicionei uma migração usando o console do gerenciador de pacotes e voila, uma migração usando RenameTable (...) foi gerada automaticamente para mim. Tenho que admitir que me certifiquei de que a única alteração na entidade foi renomeá-la para que não haja novas colunas ou colunas renomeadas, então não posso ter certeza se isso é uma coisa EF6 ou apenas que EF foi (sempre) capaz de detectar essas migrações simples.
fonte
DbSet
no seuDatabaseContext
também). Alterar a chave primária causa problemas. A migração tentará excluí-lo e criar um novo. Portanto, você precisa ajustar isso e fazer como a resposta de Chev: renomear a coluna.Nomes de tabelas e nomes de colunas podem ser especificados como parte do mapeamento de
DbContext
. Então não há necessidade de fazer isso nas migrações.fonte