2015-04-03 12 views
17

Siamo in un ambiente misto in cui la nostra applicazione utilizza sia ADO.NET che Entity Framework.
Poiché entrambi puntano allo stesso server SQL fisico, vorremmo rimuovere la stringa di connessione di Entity Framework dal file di configurazione e quindi creare automaticamente la stringa in base alle stringhe di connessione ADO.NET correnti.
Questo ci evita errori in cui uno sviluppatore ha modificato la stringa ADO.NET ma ha dimenticato di modificare la stringa di connessione di Entity Framework.Entity Framework 6 set runtime stringa di connessione

Ho letto questo ma non hanno risposto alla domanda.
How do I create connection string programmatically to MS SQL in Entity Framework 6?

Se creo la mia DbConnection e passo che al DbContext (ExistingConnection, contextOwnsConnection) allora genera un errore "Il contesto è utilizzato in codice prima modalità con il codice che è stato generato da un file EDMX per entrambi Sviluppo del database First o Model First. "

Non sto utilizzando il codice.

https://msdn.microsoft.com/en-us/data/jj680699
Questa parlato configurazione base di codice in EF 6 ma l'articolo non mostra alcun codice che effettivamente cambiato la stringa di connessione.

AGGIORNATO: ulteriori informazioni per chiarire la mia domanda.
NON sto usando il codice per primo e vorrei costruire una stringa di connessione al di fuori del file di configurazione.
Il DbContext che sto usando è una classe parziale del file DbContext generato automaticamente che il modello T4 sta generando.
Avevo l'impressione che fosse necessario creare una classe DbConfiguration ereditata e fare qualcosa in quella classe, ma l'unico che trovo è usare Azure.

C'è un articolo su Code Project che parla dell'impostazione della stringa di connessione in fase di esecuzione ma l'articolo è basato sulla creazione di una stringa di connessione ogni volta che creo un nuovo contenitore Entity.
http://www.codeproject.com/Tips/234677/Set-the-connection-string-for-Entity-Framework-at

Vorrei essere in grado di usare la mia classe DbContext parziale per creare la stringa di connessione in modo che il chiamante non deve fare nulla di speciale.

AGGIORNAMENTO: codice di lavoro per RunTime ma non designtime
Utilizzando il codice inviato da @Circular Riferimento "di seguito elencati", sono stato in grado di cambiare la stringa di connessione senza modificare le chiamate verso la mia classe entità, ma questo non funziona per il file EDMX DesignTime.

public partial class TestEntities : DbContext 
{ 
    public TestEntities() : base(GetSqlConnection(), true) 
    { 
    } 

    public static DbConnection GetSqlConnection() 
    { 
     // Initialize the EntityConnectionStringBuilder. 
     EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder(); 

     var connectionSettings = ConfigurationManager.ConnectionStrings("Current_ADO_Connection_In_Config"); 

     // Set the provider name. 
     entityBuilder.Provider = connectionSettings.ProviderName; 

     // Set the provider-specific connection string. 
     entityBuilder.ProviderConnectionString = connectionSettings.ConnectionString; 

     // Set the Metadata location. 
     entityBuilder.Metadata = "res://*/Models.TestModel.csdl|res://*/Models.TestModel.ssdl|res://*/Models.TestModel.msl"; 

     return new EntityConnection(entityBuilder.ToString()); 
    } 
} 

Ora, se riesco a far funzionare il DesignTime, ciò andrebbe bene.

+0

penso che si sarebbe utilizzando ObjectContext inste annuncio di DbContext, dal momento che non stai usando Code First. Non sono sicuro al 100% su questa relazione. Questo suggerisce: https://msdn.microsoft.com/en-us/library/bb738461(v=vs.110).aspx ed è collegato da qui descrivendo la creazione di una connessione: https://msdn.microsoft.com /en-us/library/bb738533%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396 – AaronLS

+0

Le stringhe di connessione per CodeFirst sono in genere stringhe di connessione standard, in cui le stringhe di connessione per non-CodeFirst di solito sono riferimenti a csdl/file ssdl/msl. – AaronLS

risposta

10

Si sta ottenendo l'eccezione di modalità Primo codice perché si passa un DbConnection creato con la stringa di connessione ADO.NET. Questa stringa di connessione non include riferimenti a file di metadati, quindi EntityFramework non sa dove trovarli.

Per creare un DbContext con una stringa di connessione appropriata impostata a livello di codice, utilizzare la classe EntityConnectionStringBuilder.

var entityBuilder = new EntityConnectionStringBuilder(); 

// use your ADO.NET connection string 
entityBuilder.ProviderConnectionString = conString; 

// Set the Metadata location. 
entityBuilder.Metadata = @"res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl"; 
var dbContext = new DbContext(entityBuilder.ConnectionString); 
+0

La risposta funziona ma dovrei farlo ogni volta che creo un contenitore Entity nel codice. Ho bisogno di un modo per farlo all'interno delle chiamate parziali di DbContext ... ma anche allora, non sono sicuro che funzionerà per il designer. Penso di dover fare qualcosa con DbConfiguration ma non riesco a trovare alcun buon esempio. – goroth

+0

Controlla [this] (http://forums.asp.net/t/1747809.aspx?How+to+pass+in+an++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++). Dovrai scrivere un po 'più di codice e mentre funziona, non va bene dal punto di vista della manutenibilità. Probabilmente è meglio mantenere la stringa di connessione EF nel file di configurazione. –

+0

Sarei d'accordo con questa implementazione se potessi mettermi al lavoro. Tuttavia, sto riscontrando un errore di "metadata" "non supportato da parole chiave" quando si tenta di accedere al database di contesto DB creato da quanto sopra. –

17

È possibile lavorare in fase di progettazione utilizzando la stringa di connessione nel file di configurazione.

Quindi non rimuoverlo perché ne hai bisogno SOLO in fase di progettazione.

lavoro invece in modo dinamico in fase di esecuzione utilizzando questo approccio (simile al vostro ultimo):

Estendere il contesto dati classe parziale:

public partial class DWContext 
{ 
    public DWContext(string nameOrConnectionString) 
     : base(nameOrConnectionString) 
    { 
    } 

    /// <summary> 
    /// Create a new EF6 dynamic data context using the specified provider connection string. 
    /// </summary> 
    /// <param name="providerConnectionString">Provider connection string to use. Usually a standart ADO.NET connection string.</param> 
    /// <returns></returns> 
    public static DWContext Create(string providerConnectionString) 
    { 
     var entityBuilder = new EntityConnectionStringBuilder(); 

     // use your ADO.NET connection string 
     entityBuilder.ProviderConnectionString = providerConnectionString; 

     entityBuilder.Provider = "System.Data.SqlClient"; 

     // Set the Metadata location. 
     entityBuilder.Metadata = @"res://*/Database.DWH.DWModel.csdl|res://*/Database.DWH.DWModel.ssdl|res://*/Database.DWH.DWModel.msl"; 

     return new DWContext(entityBuilder.ConnectionString); 
    } 

} 

E dal codice creare un nuovo data EF contesto con:

private DWContext db = DWContext.Create(providerConnectionString); 

Ciao ;-)

+0

Soluzione dolce e semplice, grazie :) –

+0

Questo non funziona per me, ottengo il messaggio "Questo contesto è in uso in Code First ...". –

+0

@NilsGuillermin prova a eliminare e creare nuovamente il modello di dati e assicurati di scegliere l'opzione "Crea da database esistente (Database prima)". – jacktric

Problemi correlati