2008-10-09 9 views
20

Tengo una cadena de conexión que se pasa a una función, y necesito crear un objeto basado en DbConnection (es decir, SQLConnection, OracleConnection, OLEDbConnection, etc.) basado en esta cadena.C# Recuperación del objeto DbConnection correcto por cadena de conexión

¿Hay alguna función incorporada para hacer esto o cualquier biblioteca de terceros para ayudarlo? No necesariamente estamos construyendo esta cadena de conexión, por lo que no podemos confiar en un formato de la cadena está escrito para determinar su tipo, y me prefieren no tener que codificar hasta todas las combinaciones y permutaciones de series de conexión

Respuesta

29
DbConnection GetConnection(string connStr) 
    { string providerName = null; 
     var csb = new DbConnectionStringBuilder{ConnectionString=connStr}; 

     if (csb.ContainsKey("provider")) 
     { providerName = csb["provider"].ToString(); 
     }   
     else 
     { var css = ConfigurationManager 
          .ConnectionStrings 
          .Cast<ConnectionStringSettings>() 
          .FirstOrDefault(x=>x.ConnectionString==connStr); 
     if (css != null) providerName = css.ProviderName; 
     } 

     if (providerName != null) 
     { var providerExists = DbProviderFactories 
            .GetFactoryClasses() 
            .Rows.Cast<DataRow>() 
            .Any(r=>r[2].Equals(providerName)); 
     if (providerExists) 
      { var factory = DbProviderFactories.GetFactory(providerName); 
      var dbConnection = factory.CreateConnection(); 

      dbConnection.ConnectionString = connStr; 
      return dbConnection; 
      } 
     } 

     return null; 
    } 
+0

Asimismo, no creo que vaya a funcionar para las cadenas de conexión OleDb como: Provider = Microsoft.ACE.OLEDB.12.0; Data Source = 9cb8a4c4-9661-4c10-A21C-fb4a85ce2471.xlsx; Mode = ReadWrite; Propiedades extendidas = "Excel 12.0 Xml; HDR = SÍ; IMEX = 0;" –

+0

No, solo devolverá una conexión OLEDB si el proveedor se especifica como "System.Data.OleDb" o si la cadena de conexión se especifica en la configuración. –

+0

Encuentro esto realmente sorprendente, que no puede hacer que su código sea independiente de DB sin este tipo de molestias. –

1

Debería poder analizar la sección Proveedor y pasarla a DbProviderFactories.GetFactory que devolverá una OdbcFactory, OleDbFactory o SqlClientFactory y le permitirá realizar CreateConnection, etc.

No estoy seguro de cómo funcionaría esto con Oracle, a menos que ellos proporcionan un OracleDbFactory.

18

si está utilizando Framework 2.0 o superior, y puede hacer que pasen en una segunda cadena con la clase de controlador, puede usar la clase dbProviderFactory para cargar el controlador por usted.

DbProviderFactory dbProviderFactory = DbProviderFactories.GetFactory(myDriverClass); 
DbConnection dbConnection = dbProviderFactory.CreateConnection(); 
dbConnection.ConnectionString = myConnectionString; 

He aquí un enlace de MSDN a la clase de fábrica: http://msdn.microsoft.com/en-us/library/wda6c36e.aspx

1

La mayoría de las cadenas de conexión (al menos en .NET 2.0) también tienen una propiedad providerName que va con ellos. Por lo que una cadena de conexión de SQL tendrá un proveedor de nombre como:

providerName="System.Data.SqlClient" 

Así que su método tendría que aceptar tanto la cadena de conexión y el nombre del proveedor y luego se podría utilizar el DbProviderFactory as mentioned by damieng.

Cuestiones relacionadas