12

Inizialmente si stava utilizzando EF 4.3 e con l'aggiornamento a 5.0 ho scoperto gli indici, i vincoli FK e tutti i vincoli PK le convenzioni di denominazione sono state modificate per includere dbo (ad esempio PK_Users è ora diventato PK_dbo.Users)Entity Framework Code-First Migrations - Impossibile eliminare il vincolo perché non esiste (convenzione di denominazione da 4.3 a 5.0)

Ora ogni volta che apporto una modifica al modello e deve cambiare una tabella che contiene questi elementi, la dice sempre impossibile eliminare il vincolo perché non riesce a trovarlo.

Voglio solo che quando tenta di rilasciare un vincolo/indice/chiave, prima controlla se è presente la denominazione precedente alla 5.0 e, in tal caso, rilasciarlo, ma lo ricrea ancora utilizzando la nuova 5.0 convenzioni di denominazione.

Le convenzioni di denominazione modificata in questo modo 4,3-5,0:

chiave primaria/Indici

Old: PK_Users     New: PK_dbo.Users 

chiavi esterne

Old: FK_Users_Roles_Role_Id  New: FK_dbo.Users_dbo.Roles_Role_Id    

Nota: Non posso semplicemente EF rigenerare tutte le tabelle , Ho dati di produzione in questo database. Inoltre, non desidero eseguire manualmente questa operazione per ogni tabella utilizzando le migrazioni personalizzate.

Modifica: Ho trovato una domanda simile How can I stop Entity Framework 5 migrations adding dbo. into key names? ma questo ragazzo voleva solo ignorare le convenzioni 5.0 e attenersi alla 4.3, e si occupava solo di ridenominazione della tabella. Preferirei di non farlo poiché le versioni successive di EF potrebbero causare più modifiche che potrebbero influire su questo codice e solo essere una seccatura lungo la linea.

Ho provato a fare qualcosa nella stessa vena come la risposta postato:

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.", ""); 
    } 
} 

e aggiungendolo alla configurazione:

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

    } 

Tuttavia l'errore colpisce ancora:

dbo.Users_dbo.Departments_Department_Id "non è un vincolo. Impossibile eliminare il vincolo. Vedi errori precedenti.

in realtà ho provato di override ogni singolo membro del CSharpMigrationCodeGenerator e l'impostazione di un punto di interruzione sulla dichiarazione di ritorno, e nessuno di loro ha colpito. Quindi sembra che il mio generatore personalizzato non venga mai usato, non sono sicuro di cosa mi manchi.

+0

Hai provato '-IngoreChanges', potrebbe (anche se non sicuro) in grado di aiutare - [-IngoreChanges] (http: // stackoverflow.com/a/9623319/417747). Questo potrebbe scafoldare il tuo db esistente "così com'è", ma poi devi vedere cosa succede, potrebbe funzionare con nomi esistenti. Potrebbe anche essere necessario regolare manualmente gli script di migrazione (file ####. Cs) dove/quando necessario. Probabilmente "colpirebbe un muro" a un certo punto - non penso che tu possa correre per sempre con la vecchia convenzione. Ignorare le convenzioni non è una cattiva idea per me, se possibile. Fammi sapere. – NSGaga

+0

Non voglio ignorare le modifiche, ho apportato delle modifiche che devono essere eseguite, è solo che nel farlo, cerca di fare un cambiamento con qualcosa che non esiste perché lo sta cercando tramite il nuova convenzione. Non voglio ignorare le convenzioni o attenermi a quelle vecchie. Devo solo essere in grado di dirgli come trovare la cosa che sta cercando, quindi comportarsi normalmente. Ho pensato che avrei potuto farlo cambiando il 'Nome' in" MigrationOperations' per rimuovere il dbo. riferimenti, ma non sembra essere in esecuzione. – SventoryMang

+0

Penso di capire quello che stai cercando di fare - ma non puoi fare esattamente ciò che vuoi IMO, quindi hai bisogno della prossima cosa migliore. Solo iniziando EF6 ottieni il pieno controllo sulle convenzioni, creando quelle personalizzate ecc. EF6 è già disponibile (con sorgente completa), è ancora in beta - ma non per molto - quindi forse questa è la tua opzione allora (con convenzioni personalizzate - Ho avuto un post con quello se necessario). E non è esattamente "ignorare i cambiamenti": ignori prima il "vecchio stato", quindi può "inghiottire" ciò che avevi prima (potrebbe essere necessario tornare a un codice prima). Quindi applicate le modifiche e regolate la mig. cs – NSGaga

risposta

6

Ho trovato la risposta ed è simile alla risposta nella domanda a cui ho collegato nella mia domanda. Il problema che sovrascrive lo CSharpCodeGenerator viene utilizzato solo nelle migrazioni personalizzate .

Per eseguire l'override delle migrazioni automatiche è necessario ignorare la classe SqlServerMigrationSqlGenerator e chiamare SetSqlGenerator() nella Migrazione.costruttore di configurazione:

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.", ""); 
    } 
} 

E la configurazione di migrazione:

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