ASP.NET: ¿Cómo crear una conexión desde un web.config ConnectionString?
-
20-08-2019 - |
Pregunta
¿Cómo se construye una DbConnection basada en un nombre de proveedor ?
Ejemplo de nombre del proveedor s
- System.Data.SqlClient
- System.Data.OleDb
- System.Data.Odbc
- FirebirdSql.Data.FirebirdClient
tengo cadenas de conexión almacenadas en el archivo web.config de mi 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"/>
Puede ver que todos usan diferentes proveedores. Cuando llegue el momento de crear una conexión, tengo que saber qué tipo de DbConnection crear, por ejemplo:
- SqlConnection
- OleDbConnection
- OdbcConnection
- FbConnection
Las entradas de connectionStrings contienen un proveedorNombre , pero estos no son los nombres de las clases descendientes de DbConnection, pero parecen ser un namespace
¿Cómo hago para construir un DbConnection basado en una cadena 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();
}
Solución
Si sigue esta ruta, creo que querrá usar la clase DbProviderFactories para obtener una DbProviderFactory que puede usar para construir la conexión. No he probado este código, pero creo que funcionará. Es posible que deba buscar el nombre del proveedor utilizando el método GetFactoryClasses en la clase DbProviderFactories y utilizar el 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;
}
Otros consejos
Consulte este blog de Hanselman para agregar tipos de compilación personalizados para diferentes nombres de cadenas de conexión , parece que puede ajustarse a lo que desea lograr de una manera diferente que usar los tipos de proveedor.
Si el nombre del proveedor para el nombre de conexión particular (dev, test, prod) nunca cambia, ¿por qué no puede cambiar el parámetro de nombre de conexión para su método y establecer la instancia del nombre de proveedor de esa manera?