ASP.NET: Come creare una connessione da un Web.config ConnectionString?
-
20-08-2019 - |
Domanda
Come si costruisce un DbConnection basato su un nome del provider ?
Esempio nome provider s
- System.Data.SqlClient
- System.Data.OleDb
- System.Data.Odbc
- FirebirdSql.Data.FirebirdClient
Ho stringhe di connessione memorizzate nel file web.config del mio server IIS:
<connectionStrings>
<add name="development"
connectionString="Provider = IBMDA400; Data Source = MY_SYSTEM_NAME; User Id = myUsername; Password = myPassword;"
providerName="System.Data.OleDb" />
<add name="live"
connectionString="usd=sa;pwd=password;server=deathstar;"
providerName="System.Data.Odbc" />
<add name="testing"
connectionString="usd=sa;pwd=password;server=deathstar;"
providerName="System.Data.SqlClient" />
<add name="offline"
connectionString="Server=localhost;User=SYSDBA;Password=masterkey;Charser=NONE;Database=c:\data\mydb.fdb"
providerName="FirebirdSql.Data.FirebirdClient"/>
Puoi vedere che usano tutti provider diversi. Quando arriva il momento di creare una connessione, devo sapere che tipo di DbConnection creare, ad es .:
- SqlConnection
- OleDbConnection
- OdbcConnection
- FbConnection
Le voci connectionStrings contengono un providerName , ma questi non sono i nomi delle classi discendenti di DbConnection, ma sembrano essere un spazio dei nomi
Come posso costruire un DbConnection basato su una stringa providerName ?
public DbConnection GetConnection(String connectionName)
{
//Get the connectionString infomation
ConnectionStringSettings cs =
ConfigurationManager.ConnectionStrings[connectionName];
if (cs == null)
throw new ConfigurationException("Invalid connection name \""+connectionName+"\");
//Create a connection based on the provider
DbConnection conn = new DbConnection();
}
Soluzione
Se segui questa strada, penso che vorrai usare la classe DbProviderFactories per ottenere una DbProviderFactory che puoi usare per costruire la connessione. Non ho provato questo codice, ma penso che funzionerà. È possibile che sia necessario cercare il nome del provider utilizzando il metodo GetFactoryClasses sulla classe DbProviderFactories e utilizzare InvariantName.
public DbConnection GetConnection(String connectionName)
{
//Get the connection string info from web.config
ConnectionStringSettings cs=
ConfigurationManager.ConnectionStrings[connectionName];
//documented to return null if it couldn't be found
if (cs == null)
throw new ConfigurationErrorsException("Invalid connection name \""+connectionName+"\"");
//Get the factory for the given provider (e.g. "System.Data.SqlClient")
DbProviderFactory factory =
DbProviderFactories.GetFactory(cs.ProviderName);
//Undefined behaviour if GetFactory couldn't find a provider.
//Defensive test for null factory anyway
if (factory == null)
throw new Exception("Could not obtain factory for provider \""+cs.ProviderName+"\"");
//Have the factory give us the right connection object
DbConnection conn = factory.CreateConnection();
//Undefined behaviour if CreateConnection failed
//Defensive test for null connection anyway
if (conn == null)
throw new Exception("Could not obtain connection from factory");
//Knowing the connection string, open the connection
conn.ConnectionString = cs.ConnectionString;
conn.Open()
return conn;
}
Altri suggerimenti
Dai un'occhiata a questo blog Hanselman sull'aggiunta di tipi di build personalizzati per nomi di stringhe di connessione differenti , sembra che potrebbe adattarsi a ciò che desideri ottenere in modo diverso rispetto all'utilizzo dei tipi di provider.
Se il providerName per il nome della connessione particolare (dev, test, prod) non cambia mai perché non puoi cambiare il parametro connectionName per il tuo metodo e impostare l'istanza providerName in quel modo?