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();

}
È stato utile?

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?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top