12

Używałem wcześniej EF 4.3 i po uaktualnieniu do wersji 5.0 znajduję indeksy, ograniczenia FK i ograniczenia PK wszystkie Zmieniliśmy konwencje nazewnictwa tak, aby obejmowały dbo (np. PK_Users stało się teraz PK_dbo.Users)Entity Framework Code-First Migrations - Nie można usunąć ograniczenia, ponieważ nie istnieje (konwencja nazewnictwa od 4.3 do 5.0)

Teraz za każdym razem, gdy wprowadzam zmianę do modelu i muszę zmienić tabelę, która ma w sobie to, zawsze mówi to nie można usunąć ograniczenia, ponieważ nie może go znaleźć.

Po prostu chcę, aby podczas próby usunięcia ograniczenia/indeksu/klucza najpierw sprawdzała, czy istnieje nazywanie wersji wcześniejszej niż 5.0, a jeśli tak, upuść ją, ale nadal odtwarzaj ją przy użyciu nowego 5.0 konwencje nazewnictwa.

Konwencje nazewnictwa zmieniane podobnie jak od 4,3 do 5,0:

klucz podstawowy/Indeksy

Old: PK_Users     New: PK_dbo.Users 

Klucze obce

Old: FK_Users_Roles_Role_Id  New: FK_dbo.Users_dbo.Roles_Role_Id    

Uwaga: Nie mogę po prostu mieć EF zregenerować wszystkie tabele , Mam dane produkcyjne w tej bazie danych. Nie chcę też ręcznie tego robić dla każdego stołu przy użyciu niestandardowych migracji.

Edytować: Znalazłem podobne pytanie How can I stop Entity Framework 5 migrations adding dbo. into key names?, ale ten facet chciał tylko zignorować konwencje 5.0 i trzymać się z 4.3, a to tylko zajmowało się zmiana nazwy tabeli. Wolałbym tego nie robić, ponieważ kolejne wersje EF mogą powodować więcej zmian, które mogłyby wpłynąć na ten kod i być po prostu kłopotliwe.

Próbowałem robić coś w tym samym duchu, jak odpowiedź pisał:

public class CodeMigrator : CSharpMigrationCodeGenerator 
{ 
    protected override void Generate(
     DropIndexOperation dropIndexOperation, IndentedTextWriter writer) 
    { 
     dropIndexOperation.Name = StripDbo(dropIndexOperation.Name); 
     base.Generate(dropIndexOperation, writer); 
    } 

    protected override void Generate(DropForeignKeyOperation dropForeignKeyOperation, IndentedTextWriter writer) 
    { 
     dropForeignKeyOperation.Name = StripDbo(dropForeignKeyOperation.Name); 
     base.Generate(dropForeignKeyOperation, writer); 
    } 

    protected override void Generate(DropPrimaryKeyOperation dropPrimaryKeyOperation, IndentedTextWriter writer) 
    { 
     dropPrimaryKeyOperation.Name = StripDbo(dropPrimaryKeyOperation.Name); 
     base.Generate(dropPrimaryKeyOperation, writer); 
    } 

    // TODO: Override other Generate overloads that involve table names 

    private string StripDbo(string name) 
    { 
     return name.Replace("dbo.", ""); 
    } 
} 

i dodanie go do config:

public Configuration() 
    { 
     CodeGenerator = new CodeMigrator(); 
     AutomaticMigrationsEnabled = true; 
     AutomaticMigrationDataLossAllowed = false; 

    } 

jednak błąd nadal odsłon:

dbo.Users_dbo.Departments_Department_Id 'nie jest ograniczeniem. Nie można usunąć ograniczenia. Zobacz poprzednie błędy.

I rzeczywiście próbował Zastąp każdy pojedynczy element w CSharpMigrationCodeGenerator i ustawienie przerwania na instrukcji return, a żaden z nich uderzył. Wygląda na to, że mój niestandardowy generator nigdy się nie przyzwyczaja, nie jestem pewien, czego mi brakuje.

+0

próbowałaś '-IngoreChanges', to może (choć nie jestem pewien) będzie w stanie pomóc - [-IngoreChanges] (http: // stackoverflow.com/a/9623319/417747). To by zmobilizowało twój istniejący db "jak jest" - ale wtedy musisz zobaczyć, co się stanie, może działać z istniejącym nazewnictwem. Konieczne może być również ręczne dostosowanie skryptów migracji (####. Cs) w razie potrzeby. Prawdopodobnie w pewnym momencie "uderzyłby w ścianę" - nie sądzę, żebyś mógł biegać ze starą konwencją na zawsze. Ignorowanie konwencji nie jest dla mnie złym pomysłem, jeśli to możliwe. Daj mi znać. – NSGaga

+0

Nie chcę ignorować zmian, wprowadziłem zmiany, które należy uruchomić, po prostu próbuję dokonać zmiany za pomocą czegoś, co nie istnieje, ponieważ szuka tego za pośrednictwem nowa konwencja. Nie chcę ignorować konwencji lub trzymać się starej. Po prostu muszę umieć powiedzieć, jak znaleźć to, czego szuka, a potem zachowywać się normalnie. Pomyślałem, że mogę to zrobić, zmieniając 'Name' w' MigrationOperations', aby usunąć dbo. referencje, ale wygląda na to, że nie działa. – SventoryMang

+0

Myślę, że rozumiem, co próbujesz zrobić - ale nie możesz zrobić "dokładnie" tego, co chcesz IMO, więc potrzebujesz następnej najlepszej rzeczy. Tylko zaczynając EF6 masz pełną kontrolę nad konwencjami, tworzenie niestandardowych itp. EF6 jest już dostępny (z pełnym źródłem), jest w fazie beta - ale nie na długo - więc może to twoja opcja (z niestandardowymi konwencjami - miałem post z tym w razie potrzeby). I nie jest to dokładnie "ignorowanie zmian" - najpierw ignorujesz "stary stan", aby "połknąć" to, co miałeś wcześniej (być może będziesz musiał wcześniej wrócić do kodu). Następnie zastosuj zmiany i dostosuj mig. cs – NSGaga

Odpowiedz

6

Wyjaśniałem odpowiedź i jest ona podobna do odpowiedzi w pytaniu, które zawierałem w moim pytaniu. Problem z przesłonięciem CSharpCodeGenerator jest używany tylko w niestandardowych migracjach .

Aby zastąpić automatyczne migracje, należy przesłonić klasę SqlServerMigrationSqlGenerator i wywołać SetSqlGenerator() w migracji.konstruktor konfiguracja:

public class SqlMigrator : SqlServerMigrationSqlGenerator 
{ 
    protected override void Generate(DropForeignKeyOperation dropForeignKeyOperation) 
    { 
     dropForeignKeyOperation.Name = StripDbo(dropForeignKeyOperation.Name); 
     base.Generate(dropForeignKeyOperation); 
    } 

    protected override void Generate(DropIndexOperation dropIndexOperation) 
    { 
     dropIndexOperation.Name = StripDbo(dropIndexOperation.Name); 
     base.Generate(dropIndexOperation); 
    } 

    protected override void Generate(DropPrimaryKeyOperation dropPrimaryKeyOperation) 
    { 
     dropPrimaryKeyOperation.Name = StripDbo(dropPrimaryKeyOperation.Name); 
     base.Generate(dropPrimaryKeyOperation); 
    } 

    private string StripDbo(string name) 
    { 
     return name.Replace("dbo.", ""); 
    } 
} 

A config migracja:

public Configuration() 
    { 
     AutomaticMigrationsEnabled = true; 
     AutomaticMigrationDataLossAllowed = false; 
     SetSqlGenerator("System.Data.SqlClient", new SqlMigrator()); 
    } 
Powiązane problemy