2012-04-11 35 views
13

¿Cuáles son las principales ventajas de cada uno de los métodos de conexión de base de datos anteriores en C# en términos de conexión a múltiples fuentes de datos posibles (siendo agnóstico de base de datos)? ¿También en términos de rendimiento que es probable que ofrezca el mejor rendimiento en todos los ámbitos?DbConnection vs OleDbConnection vs OdbcConnection

Finalmente, ¿hay alguna razón para evitar un método particular para una aplicación de base de datos independiente?

La razón por la que pregunto es porque mi aplicación actualmente utiliza Ole y tengo algunos problemas para conectarme a ciertas bases de datos usando fábricas y, como tal, estoy buscando alternativas. He oído que Odbc es más lento que Ole, pero ¿hay algo de verdad detrás de esto y es realmente notable en una aplicación real?

razón de mi interés en este tema es el siguiente:

Mis requisitos para mi estado actual proyecto que debo tener una capa de acceso de datos de trabajo que es capaz de conectarse a cualquier base de datos sin el conocimiento previo de dicha base de datos. Por lo tanto, no puedo codificar cualquier cosa específica para una base de datos dada en términos de conexión. La ejecución de enunciados específicos del dialecto en cada base de datos dada se ha tratado utilizando un concepto de tipo de fábrica de consultas sql. Lo mismo ocurre con la sustitución y el formato de las variables de vinculación.

ACTUALIZACIÓN: Tal como está, ahora tengo una versión funcional de mi código que utiliza ADO.net y las fábricas de proveedores de bases de datos. Esto significa que estoy usando las clases base como lo sugirió Adam Houldsworth. El proveedor se especifica en la cadena de conexión bajo el atributo providerName. La cadena de conexión se almacena en la aplicación.config, donde puede ser recuperada por mi clase de conexión de base de datos. Siempre que se haya instalado el controlador correcto, como npgsql o el paquete odac para Oracle, la fábrica funcionará correctamente. A continuación se muestra una muestra de mi código que muestra el constructor básico para un objeto de conexión que utiliza una fábrica de proveedores.

private readonly DbFactoryBindVariables m_bindVariables; 
private readonly DbProviderFactory m_provider; 
private string m_connectionString = String.Empty; 
private readonly string m_providerName = String.Empty; 
private DbConnection m_dbFactoryDatabaseConnection; 


/// <summary> 
/// Default constructor for DbFactoryDatabaseConnection. 
/// </summary> 
public DbProviderFactoryConnection() 
{ 
     m_providerName = ConfigurationManager.ConnectionStrings["ApplicationDefault"].ProviderName; 
     m_provider = DbProviderFactories.GetFactory(m_providerName); 

     m_dbFactoryDatabaseConnection = m_provider.CreateConnection(); 

     m_connectionString = ConfigurationManager.ConnectionStrings["ApplicationDefault"].ConnectionString; 
     m_dbFactoryDatabaseConnection.ConnectionString = m_connectionString; 

     m_bindVariables = new DbFactoryBindVariables(m_dialect.ToLower(), DbFactoryBindSyntaxLoader.Load(this)); 
} 

puede ser necesario añadir algo similar a lo siguiente en el app.config o web.config si no está ya presente en el machine.config para su versión de .NET Framework elegido.

<system.data> 
    <DbProviderFactories> 
     <add name="Npgsql Data Provider" 
     invariant="Npgsql" 
     support="FF" 
     description=".Net Framework Data Provider for Postgresql Server" 
     type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.1.0, Culture=neutral, 
     PublicKeyToken=5d8b90d52f46fda7" /> 
    </DbProviderFactories> 
</system.data> 

Cadena de conexión requerido:

<add name="ApplicationDefault" connectionString="DATA SOURCE=TNSNAME;PASSWORD=PASS;USER ID=USER;" providerName="Oracle.DataAccess.Client;"/> 

En esta etapa que ahora puede ser totalmente agnóstico base de datos siempre que la cadena de conexión correcta se utiliza para configurar la versión de los clientes de la aplicación.

+0

Agregó una actualización para los interesados. – CSharpened

Respuesta

5

Evitaría abstraer la conexión a la base de datos ya que siempre se está orientando al mínimo común denominador. En cambio, intente abstraer el requisito de guardar las entidades. Cada implementación de esa abstracción puede ser específica de la base de datos (básicamente, programación contra interfaces).

Dicho esto, no he experimentado una instancia en la que necesite soportar múltiples bases de datos. En este caso, todo este agravamiento se encuentra con el mantra YAGNI.

Una pregunta sobre la comparación de OLE DB para ODBC en general, se puede encontrar aquí:

what is the difference between OLE DB and ODBC data sources?

Aunque las preguntas de rendimiento inicial es una buena cosa, la pregunta no puede ser respondida en el contexto de su aplicación. Lamentablemente, solo los perfiles de ambos contra los datos de muestra le darán las respuestas que necesita.

No hay mucho que destacar sobre DbConnection, es la clase base para las otras clases de conexión específicas de la base de datos.

¿Has considerado un ORM como NHibernate o un marco como el Enterprise Library Data Access Application Block? Esto lo ayudará a abstraer la base de datos (con ORM, hasta el punto que ni siquiera necesita hacer ninguna codificación en la base de datos).

Actualización: por lo que yo puedo decir por los comentarios, parece como si su única opción es utilizar las clases base .NET proporcionados (como DbConnection) o las interfaces (IDbConnection). Que yo sepa, no hay nada que pueda darle la conexión correcta para una cadena de conexión, por lo que puede que tenga que codificar esa parte. De esta manera, puede devolver OleDbConnection, OdbcConnection, SqlConnection, etc. cuando detecta la cadena de conexión, pero úselas en el código como DbConnection o IDbConnection, manteniendo así el código de la base de datos subyacente.

No es ideal, pero funciona perfectamente.

+0

Gracias por la buena respuesta. Al programar contra las interfaces, supongo que te refieres a que sería más inteligente tener una interfaz que luego se implemente varias veces para cada fuente de datos. El problema con esto es que no tendré conocimiento previo de la fuente de datos y solo recibiré una cadena de conexión de web.config (cambios para cada configuración de usuario configurada) que dicta la fuente de datos a la cual conectarse. Esto significa que tendría que codificar una implementación para cada fuente de datos posible, lo que parecería demasiado pesado si, por ejemplo, solo terminamos necesitando de 4 a 6 plataformas diferentes. – CSharpened

+1

@CSharpened Debe tener conocimiento previo de las posibles bases de datos con las que su aplicación funcionará. Si no lo hace, todo lo que puede hacer es utilizar el mecanismo de conexión común más bajo y SQL ANSI, por lo que OLE u ODBC. La pregunta sobre la idoneidad es entonces: de todas las bases de datos que tiene que admitir, ¿ofrecen acceso ODBC u OLEDB? –

+0

Definitivamente no tendré conocimiento previo, ya que mi código necesita poder simplemente usar cualquier cadena de conexión que se transfiera para establecer una conexión. Es frustrante, pero estos son los requisitos que me han dado. Si resulta inviable, entonces está bien, ya que simplemente refuta el concepto que se me ha pedido. La mayoría de las fuentes de datos que he utilizado hasta ahora admiten al menos una, pero podría haber un problema con las más oscuras.En esta etapa me pidieron que proporcione soporte para Oracle, PostgreSQL, SQL Server, MySQL y Spatialite más uno o dos más. – CSharpened

3

El uso de DbProviderFactory es una buena opción si necesita tener una capa de acceso a datos agnósticos, sin codificar el acceso a los datos más de una vez.

No veo ningún motivo por el que quiera evitarlo y toda la funcionalidad necesaria se cubre utilizando las clases base en System.Data.Common.

Estamos utilizando un acceso de datos agnóstico en Nearforums porque entregamos scripts de SQL Server y MySql db. Sobre el rendimiento, depende de las implementaciones de conector específico (Oracle, MySql, PostgreSQL, ...) entregados por las diferentes compañías/comunidades. La mayoría de los conectores conocidos se han probado correctamente durante varios años.

+0

¿Quiere decir usar DbProviderFactory con un objeto DbConnection básico? – CSharpened

+1

Derecha, puede ver un ejemplo aquí: http://davidhayden.com/blog/dave/archive/2007/10/08/CreatingDataAccessLayerUsingDbProviderFactoriesDbProviderFactory.aspx – jorgebg

+1

Gracias por eso. Lo leeré bien. – CSharpened

Cuestiones relacionadas