Zmieniłem nazwy kilku jednostek i ich właściwości nawigacyjnych i wygenerowałem nową migrację w EF 5. Jak zwykle w przypadku zmian nazw w migracjach EF, domyślnie zamierzałem porzucić obiekty i je odtworzyć. Nie tego chciałem, więc prawie musiałem zbudować plik migracji od zera.
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");
}
Wszystko, co próbuję zrobić, to zmienić nazwę dbo.ReportSections
na, dbo.ReportPages
a następnie dbo.ReportSectionGroups
na dbo.ReportSections
. Następnie muszę zmienić nazwę kolumny klucza obcego dbo.ReportPages
z Group_Id
na Section_Id
.
Porzucam klucze obce i indeksy łączące tabele, potem zmieniam nazwy tabel i kolumny klucza obcego, a następnie ponownie dodaję indeksy i klucze obce. Zakładałem, że to zadziała, ale pojawia się błąd SQL.
Msg 15248, poziom 11, stan 1, procedura sp_rename, wiersz 215 albo parametr @objname jest niejednoznaczny, albo żądany @objtype (COLUMN) jest nieprawidłowy. Msg 4902, poziom 16, stan 1, wiersz 10 Nie można znaleźć obiektu „dbo.ReportSections”, ponieważ nie istnieje lub nie masz uprawnień.
Nie mam łatwo dowiedzieć się, co jest nie tak. Każdy wgląd byłby niezwykle pomocny.
Odpowiedzi:
Nieważne. Robiłem to bardziej skomplikowanym, niż było to naprawdę konieczne.
To było wszystko, czego potrzebowałem. Metody zmiany nazwy po prostu generują wywołanie procedury przechowywanej w systemie sp_rename i myślę, że zadbała o wszystko, w tym klucze obce z nową nazwą kolumny.
źródło
RenameColumn
generujesp_rename
instrukcję T-SQL używającąparsename
wewnętrznie, która ma pewne ograniczenia. Więc jeśli masz nazwę tabeli, która zawiera kropki, np. „SubSystemA.Tablename”, użyj:RenameColumn("dbo.[SubSystemA.Tablename]", "OldColumnName", "NewColumnName");
RenameIndex(..)
podczas migracji, aby zmienić jego nazwęRenameTable(..)
aby zmienić nazwy FK i PK. To nie brzmi dobrze, ale to działa dla mnie. Jest to metoda, która tworzy poprawną T-SQL (execute sp_rename ...
). Jeśli wykonasz update-database -verbose, zobaczysz to na własne oczy.Jeśli nie lubisz ręcznie pisać / zmieniać wymaganego kodu w klasie Migration, możesz zastosować dwuetapowe podejście, które automatycznie tworzy
RenameColumn
wymagany kod:Krok pierwszy Użyj,
ColumnAttribute
aby wprowadzić nową nazwę kolumny, a następnie dodaj migrację (np.Add-Migration ColumnChanged
)Krok drugi: Zmień nazwę właściwości i ponownie zastosuj do tej samej migracji (np.
Add-Migration ColumnChanged -force
) W konsoli Menedżera pakietówJeśli spojrzysz na klasę migracji, zobaczysz, że automatycznie wygenerowany kod to
RenameColumn
.źródło
The name 'Rename_SalesArea' is used by an existing migration.
-force
parametr podczas korzystania z migracji dodawaniaAby nieco rozwinąć odpowiedź Hosseina Narimani Rad, możesz zmienić nazwę zarówno tabeli, jak i kolumn, używając odpowiednio System.ComponentModel.DataAnnotations.Schema.TableAttribute i System.ComponentModel.DataAnnotations.Schema.ColumnAttribute.
Ma to kilka zalet:
Na przykład dodanie
[Table("Staffs")]
:Wygeneruje migrację:
źródło
W EF Core używam następujących instrukcji do zmiany nazw tabel i kolumn:
Jeśli chodzi o zmianę nazw tabel:
Jeśli chodzi o zmianę nazw kolumn:
źródło
W ef core można zmienić migrację, która została utworzona po dodaniu migracji. A następnie wykonaj aktualizację bazy danych. Próbka podała poniżej:
źródło
Właśnie spróbowałem tego samego w EF6 (zmiana nazwy pierwszej jednostki kodu). Po prostu zmieniłem nazwę klasy i dodałem migrację za pomocą konsoli menedżera pakietów i voila, migracja za pomocą RenameTable (...) została automatycznie wygenerowana dla mnie. Muszę przyznać, że upewniłem się, że jedyną zmianą w encji była zmiana jej nazwy, więc nie ma nowych kolumn ani kolumn o zmienionych nazwach, więc nie mogę być pewien, czy jest to sprawa EF6, czy po prostu EF był (zawsze) w stanie wykryć takie proste migracje.
źródło
DbSet
w twoimDatabaseContext
). Zmiana klucza podstawowego powoduje problemy. Migracja spróbuje go usunąć i utworzyć nową. Więc musisz to dostosować i zrobić tak, jak odpowiedź Cheva, zmień nazwę kolumny.Nazwy tabel i nazw kolumn można określić jako część odwzorowania
DbContext
. Wtedy nie ma potrzeby tego robić w przypadku migracji.źródło