vtortola.Net

Abril 25, 2007

DbFactory con ADO.NET 2.0 (Actualizado)

Archivado en: .NET, ADO.NET, C#, Recurso MSDN — vtortola @ 10:40 am
He actualizado el ejemplo para usar las facilidades para configurar connection strings que aporta .NET 2.0. En concreto el objeto ConfigurationManager, su propiedad ConnectionStrings y su apartado XML en el app.config.

Muchas veces, nos encontramos ante la necesidad de escribir aplicaciones que puedan trabajar con cualquier tipo de base de datos, evitando en la máxima medida tener que modificar el código de la aplicación para ello. Para solventar este problema, siempre se ha recurrido al “modelo de n capas” donde una de ellas, era el proveedor de acceso a datos y se encargaba de abstraer esta tarea, normalmente encapsulada en una librería “.dll” que se cambiaba a voluntad sin que ello supusiese ningún problema para la aplicación. Esta librería, suele contener lo que se denomina un DBFactory, una clase abstracta o conjunto de funciones encargadas de adaptarse a la base de datos que se le indique y obtener datos de forma transparente para su consumidor, esta semana he descubierto como hacerlo con ADO.NET 2.0 sin tener que codificar a penas nada con las clases que “habitan” en System.Data.Common.

El ejemplo lo voy a hacer con SQL Server 2005 Express Edition y la base de datos de ejemplo “Northwind” que trae por defecto :) .

Primero, añadiremos a nuestro archivo de configuración la sección “connectionStrings” y añadiremos una:

<?xml version=1.0 encoding=utf-8 ?>
<
configuration>
<
configSections>
</
configSections>
<
connectionStrings>
<
add name=SQLServer
connectionString=Data Source=VALERIANO\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True
providerName=System.Data.SqlClient/>
</
connectionStrings>
</
configuration>

Aseguraos de que añadís una referencia a “System.Configuration” y también la correspondiente clausula “using”. Configuramos un nombre, que será la clave en la colección, la connection string y el nombre del ensamblado que contiene el proovedor, en este caso para SQL Server usaremos “System.Data.SqlClient” (que no es ni más ni menos que el namespace que declarariamos para usarlo tal cual en nuestro código ;) ). Una vez hecho esto, ya podemos configurar las conexiones que necesitemos en el archivo de configuración y recuperarlas por su nombre, este dato también podría ir en el archivo de configuración, así solo cambiando este nombre nuestra aplicación usaría una BD u otra. Podemos añadir tantas connection strings como queramos.

Recordad que podemos consultar practicamente cualquier connection string para cualquier tipo de base de datos en ConnectionStrings.com (link que debe ir directo a vuestros bookmarks ;) ).

Ahora simplemente se trata de crear los objetos base a partir de los datos obtenidos, aquí un sencillo ejemplo:

string sqlcommand = “SELECT * FROM ORDERS”;

// Obtengo el proovedor y la connectionstring del archivo de configuración

string provider = ConfigurationManager.ConnectionStrings["SQLServer"].ProviderName;
string connectionString = ConfigurationManager.ConnectionStrings["SQLServer"].ConnectionString;

// Obtengo el proovedor.
DbProviderFactory dbpf = DbProviderFactories.GetFactory(provider);

// Creo la conexión y el comando.
using(DbConnection dbcon = dbpf.CreateConnection())
using (DbCommand dbcmd = dbcon.CreateCommand())
{

// Procedo normalmente
dbcon.ConnectionString = connectionString;
dbcon.Open();

// La select que se quiere lanzar.
dbcmd.CommandText = sqlcommand;

// Leo con un DataReader:
using (DbDataReader dbr = dbcmd.ExecuteReader())
{

string example = string.Empty;
while (dbr.Read())
{

example = dbr["CustomerID"].ToString();
Console.WriteLine(example);

}

}

// Ahora con un DataAdaptater
using(DbDataAdapter dbda = dbpf.CreateDataAdapter())
using(DataSet ds = new DataSet(“example”))
{

dbda.SelectCommand = dbcmd;
dbda.Fill(ds);

foreach (DataRow dr in ds.Tables[0].Rows)
Console.WriteLine(dr["CustomerID"].ToString());

}

}

Para más información, visitar Writing Provider-Independent Code in ADO.NET.

2 comentarios »

  1. Creo yo que siempre sera mas optimo usar el proovedor específico de la base de datos a la que te vayas a conectar en lugar de uno genererico.

    Si, asi es mas polivalente, pero si hay distintos proovedores por algo sera.

    comentario por David — Junio 15, 2007 @ 12:34 pm

  2. Hola David.
    No, esto no se trata de una conexión OLEDB o un ODBC. Como explicaba por ahi arriba, las claes de System.Data.Common son la clase base de cualquier proovedor, es decir, DBConnection es la clase de la que hereda SQLConnection, OracleConnection, OleDbConnection, ..etc.. etc.. Puedes ver esto en este ejemplo haciendo un:’Debug.Print(dbcon.GetType().Name);’, veras que en tiempo de ejecución te dice que estas usando un ‘SqlConnection’. En que convierte al final lo indicamos con el campo Provider de la connection string, por lo que siempre estamos utilizando el más óptimo ;)
    El handicap está, como en cualquer tema de polimorfismo similar, en que no podríamos llamar a métodos específicos de la clase derivada, como podría ser el método .ExecuteOracleScalar() de un OracleCommand para tratar con tipos de dato Oracle, aunque si podríamos usar el método .ExecuteScalar() común en todos los objetos comando. Por eso un Db Factory no siempre es la solución más adecuada siempre.
    Espero haber aclarado algo!!
    Un saludo.

    comentario por vtortola — Junio 15, 2007 @ 4:17 pm


Canal RSS de los comentarios de la entrada. URI para TrackBack.

Deja un comentario

Tienes que iniciar sesión para escribir un comentario.

Blog de WordPress.com.