ASP.NET: Como criar uma conexão de um ConnectionString web.config?
-
20-08-2019 - |
Pergunta
Como você construir um DbConnection com base em um nome do fornecedor ?
Amostra nome do fornecedor s
- System.Data.SqlClient
- System.Data.OleDb
- System.Data.Odbc
- FirebirdSql.Data.FirebirdClient
i ter seqüências de conexão armazenadas no arquivo web.config do meu servidor 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"/>
Você pode ver todos eles usam diferentes provedores. Quando chega a hora para mim para criar uma conexão, eu tenho que saber que tipo de DbConnection para criar, por exemplo:.
- SqlConnection
- OleDbConnection
- OdbcConnection
- FbConnection
As entradas ConnectionStrings contém um providerName , mas estes não são os nomes das classes descendentes DbConnection, mas parece ser um namespace
Como faço para transformar construir um DbConnection com base em uma string 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();
}
Solução
Se você percorrer esse caminho, eu acho que você vai querer usar a classe DbProviderFactories para obter um DbProviderFactory que você pode usar para construir a conexão. Eu não tentei isso código, mas acho que ele vai trabalhar. É possível que você pode precisar de olhar para cima o nome do provedor usando o método GetFactoryClasses na classe DbProviderFactories e usar o 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;
}
Outras dicas
Confira este Hanselman blogue sobre a adição de tipos de compilação personalizados para diferentes nomes seqüências de conexão , parece que ele pode caber o que você quer realizar de uma maneira diferente do que usando os tipos de provedor.
Se o providerName para o nome da conexão particular (dev, teste, prod) nunca muda por que não pode você fazer um interruptor no param connectionName para o seu método e definir a instância providerName assim?