Setup Entity Framework per la stringa di connessione dynamic

Sto lavorando a un’app che utilizzerà lo stesso schema di database su più database. Per questo motivo, ho creato un database chiamato MyTemplate . Quando viene creato un nuovo utente, avranno la propria istanza del database. Quindi, verrà creato un database chiamato qualcosa come MyTemplate_[UserName] . Quando un utente accede, ho bisogno di indirizzare le loro query al loro database. Per questo motivo, so che ho bisogno di impostare la stringa di connessione in fase di esecuzione. Il mio problema è che voglio anche usare Entity Framework.

Attualmente, ho creato un nuovo .edmx usando MyTemplate come origine. Pensavo di essere in grado di aggiornare il codice e impostare la stringa di connessione lì. Sfortunatamente, non riesco a capire come impostarlo. Il costruttore di TemplateEntities non ha un sovraccarico che mi consente di passare una stringa di connessione. Ho notato che TemplateEntities derivato da DbContext, non penso che questo sarebbe il problema.

 string connectionString = GetUsersConnectionString(); using (TemplateEntities entities = new TemplateEntities()) { TemplateEntity entity = new TemplateEntity(); // Save to the database entities.TemplateEntity.Add(entity); entities.SaveChanges(); } 

Sto creando il .edmx modo errato? O mi manca qualcosa del tutto? Tutto ciò che Google mostra è un sovraccarico che dovrebbe consentire l’inoltro di una stringa di connessione. Tuttavia, non è disponibile tale sovraccarico.

La class TemplateEntities generata è contrassegnata come partial .

Tutto quello che devi fare è aggiungere un altro file con un’altra parte della definizione di class parziale che espone il costruttore che vuoi usare:

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

Quindi passare la stringa di connessione a questo costruttore.

Si desidera inserire questo codice in un file diverso in modo che non venga sovrascritto quando si aggiorna il modello edmx.

La risposta di Nicholas Butler è abbastanza corretta. In aggiunta a ciò che ha detto, mi sono trovato a dover affrontare il problema di prendere una stringa di connessione esistente per il framework di quadro e semplicemente puntarla su un database diverso che avesse la stessa struttura. Ho usato il seguente codice per modificare solo l’origine dati della stringa esistente:

 var originalConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["CSName"].ConnectionString; var ecsBuilder = new EntityConnectionStringBuilder(originalConnectionString); var sqlCsBuilder = new SqlConnectionStringBuilder(ecsBuilder.ProviderConnectionString) { DataSource = "newDBHost" }; var providerConnectionString = sqlCsBuilder.ToString(); ecsBuilder.ProviderConnectionString = providerConnectionString; string contextConnectionString = ecsBuilder.ToString(); using (var db = new SMSContext(contextConnectionString)) { ... } 

Questo è il passaggio che ho usato durante la creazione delle mie soluzioni:

  1. Sul progetto desiderato, assicurarsi che Entity Framework sia stato installato utilizzando il menu di opzioni “Gestisci pacchetti Nuget …”.
  2. Nel progetto desiderato, fai clic con il pulsante destro del mouse, quindi Aggiungi-> Nuovo elemento, vai a Dati e seleziona Modello dati quadro ADO.NET.
  3. Digita il nome del modello, diciamo “EsempioModello”. Fai clic su Aggiungi.
  4. Appariranno quattro scelte per scegliere i contenuti del Modello, di solito seleziono il primo, per build il modello dagli oggetti esistenti dal database. Fare clic su Avanti.
  5. Imposta la tua connessione dati. Una volta terminato, digita il nome della tua quadro modello, diciamo “ExampleModelEntities”, fai clic su Avanti.
  6. Seleziona gli oggetti dal database che saranno presenti sul tuo modello EF. Nella casella di input Spazio dei nomi modello digitare lo stesso nome del modello del passaggio 3 (“EsempioModello”). Fai clic su Fine.

A questo punto è stato creato e aggiunto al progetto un nuovo file .edmx, contenente tutti gli oggetti pronti per il lavoro. Solo i dettagli non desiderati sono, finora, la stringa di connessione è stata specificata e salvata nel file Web.config del nostro progetto.

Per rimuovere questo, basta andare al blocco di sezione di Web.config ed eliminare i dettagli da lì. Ora lavoreremo per rendere la stringa di connessione leggibile dynamicmente da altre fonti.

Come sottolineato da Nicholas Butler, la prossima cosa sarà creare una “versione” della class di entity framework parziale originale creata (ExampleModelEntities), che ci permetterà di passare la stringa di connessione dynamic. Questo è ansible poiché la class entity framework originale creata eredita da DBContext, che è quella che contiene il costruttore per passare tale connessione.

Per fare quanto sopra, aggiungi una nuova class vuota al tuo progetto. Assicurati di digitare lo stesso nome fornito nel passaggio 5, seguendo il nostro caso studio “ExampleModelEntities”. Sotto il codice da implementare:

C #

 public partial class ExampleModelEntities { public ExampleModelEntities(string connString) : base(connString) { } } 

VB.Net:

 Partial Public Class ExampleModelEntities Public Sub New(ByVal connString As String) MyBase.New(connString) End Sub End Class 

In questo momento il tuo codice è pronto per funzionare con stringhe di connessione dinamiche provenienti da altre fonti. Una di queste fonti potrebbe passare una stringa di connessione proveniente da un altro campo memorizzato su un altro database o utilizzando la class EntityConnectionStringBuilder .

Il seguente esempio è implementato in VB.Net, ma per favore usa qualche strumento come Telerik per tradurre. Diciamo che stiamo ottenendo un elenco di oggetti da un determinato database, solo che vogliamo passare dynamicmente la stringa di connessione proveniente da un altro campo memorizzato su un altro database. Per fare ciò, il codice dovrebbe apparire come segue:

 Public Shared Function Get_List(ByVal Param1 As String) As List(Of Stored_Procedure_Code_Result) Try Dim Object_List_Result As List(Of Stored_Procedure_Code_Result) = Nothing Using dbContext As New ExampleModelEntities(Configuration.CONNECTION_STRING) Object_List_Result = dbContext.Stored_Procedure_Code(Param1).ToList dbContext.Dispose() End Using Return Object_List_Result Catch ex As Exception Throw ex End Try End Function 

Dove Configuration.CONNECTION_STRING è il valore della stringa di connessione dynamic, espressa utilizzando un modulo chiamato “Configuration” e una funzione che recupera tale valore.

Per evitare imprecisioni nel formato, il valore deve essere memorizzato utilizzando il seguente formato:

Per l’autenticazione di Windows utilizzando Entity Framework:

 UPDATE [DBConnections].[dbo].[ListOfConnectionsTable] SET ConnValue = 'metadata=res://*/ExampleModel.csdl|res://*/ExampleModel.ssdl|res://*/ExampleModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=ServerName;Initial Catalog=DBName;Integrated Security=True"' 

Per l’autenticazione SQL utilizzando Entity Framework:

 UPDATE [DBConnections].[dbo].[ListOfConnectionsTable] SET ConnValue = 'metadata=res://*/ExampleModel.csdl|res://*/ExampleModel.ssdl|res://*/ExampleModel.msl;provider=System.Data.SqlClient;provider connection string="Persist Security Info=False;User ID=XXXXXX;Password=XXXXXXX;Initial Catalog=DBName;Data Source=ServerName;App=YourAppName;Network Library=dbmssocn"' 

Infine, estendendo la risposta fornita da Mark, in Microsoft c’è una spiegazione dettagliata su come lavorare con la class EntityConnectionStringBuilder, che può essere utilizzata anche per build stringhe di connessione dinamiche e quindi trasmettere questo valore su richiesta.