Ejemplos Data Access Enterprise Library

En este tutorial revisaremos varios ejemplos de tareas comunes de acceso de datos usando Data Access Application Block de Enterprise Library.
Este tutorial construye a partir del Tutorial Introductorio, usando la misma base de datos (AdventureWorks) y configuración.

Puede descargar el codigo fuente (proximamente). Para ejecutar la aplicacion de ejemplo debe configurar la conexion a la base de datos segun se explica en el tutorial introductorio.

Como preparacion adicional tutorial introductorio debemos importar el espacio de nombre System.Data.Common:

using System.Data.Common;

En este espacio de nombres encontramos objetos como DbCommand, DbParameter, DbDataReader que nos permiten realizar las tareas de acceso a dato sin usar objetos particulares a un motor de base de datos en especifico. El objeto DataBase de Enterprise Library recibe y devuelve objetos de estos tipos para facilitar escribir codigo portable entre sistemas de bases de datos.



Obtener un dato puntual

En este ejemplo obtenemos la fecha de nacimiento de un empleado según su id. Primero creamos el objeto DataBase, luego llamamos el metodo ExecuteScalar para ejecutar la consulta pasando como primer parametro el enumerado CommandType.Text que indica que es una consulta SQL a diferencia de un Procedimiento almacenado. El segundo parametro es la consulta SQL a ejecutar.
El metodo ExecuteScalar devuelve el un dato puntual. Si la consulta genera como resultado mas de una fila, ExecuteScalar toma solo la primera fila. El resultado es devuelto en una variable de tipo object, convertimos el resultado a DateTime.

public DateTime GetFechaNacimiento(int id)
{
    Database dataBase = DatabaseFactory.CreateDatabase("AdventureWorks");
    string sql = "SELECT BirthDate FROM HumanResources.Employee WHERE EmployeeID=" + id;
    object obj = dataBase.ExecuteScalar(CommandType.Text, sql);
    DateTime fecha = Convert.ToDateTime(obj);
    return fecha;
}


Obtener un dato puntual usando un comando

Este ejemplo general el mismo resultado que el anterior, la diferencia es que usamos un comando para expresar la consulta SQL, a diferencia del caso anterorio en que la id es concatenada a la consulta SQL.
Usar comandos es especialmente importante para valores de texto que son ingresados por el usuario. Si concatenamos un string ingresado por el usuario nos hacemos vulnerables a inyeccion de SQL. Usando comandos y parametros neutralizamos esta amenaza.
Usamos el metodo GetSqlStringCommand() para obtener un objeto DbCommand adecuado para la base de datos. El metodo AddInParameter() permite agregar un parametro al comando, en este caso con nombre "@Id", tipo de datos “DbType.Int32” y el valor. El nombre del parametro debe coincidir con el marcador que incluimos en la clausula Where de la instrucción SQL.

public DateTime GetFechaNacimientoCommand(int id)
{
    Database dataBase = DatabaseFactory.CreateDatabase("AdventureWorks");
    string sql = "SELECT * FROM HumanResources.Employee WHERE Id=@Id";
    DbCommand cmd = dataBase.GetSqlStringCommand(sql);
    dataBase.AddInParameter(cmd, "Id", DbType.Int32, id);
    object obj = dataBase.ExecuteScalar(cmd);
    DateTime fecha = Convert.ToDateTime(obj);
    return fecha;
}


Iterar con un Resultset con DataReader

En este ejemplo generamos una lista con los nombres de los productos de la empresa Adventure Work. Para ello obtenemos el objeto DataBase y ejecutamos una consulta SQL con el método ExecuteReader. El método ExecuteReader devuelve un objeto IDataReader que permite iterar por las filas seleccionadas en la consulta. Usamos la instruccion "using" para asegurar que el DataReader y la Conexión se cierren apenas terminemos de utilizarlos. La instruccion "using" es una facilidad del lenguaje c# para trabajar con el patrón Dispose.
El objeto IDataReader que devuelve el método ExecuteReader esta configurado para cerrar la conexión automáticamente la cerrarse. Usamos el loop while para ir fila por fila agregando los nombres de los productos a la lista genérica, y finalmente la devolvemos.

public List<string> GetListNombres()
{
    Database dataBase = DatabaseFactory.CreateDatabase("AdventureWorks");
    string sql = "SELECT Name FROM Production.Product";
    var list = new List<string>();
    using (IDataReader dr = dataBase.ExecuteReader(CommandType.Text, sql))
    {
        while (dr.Read())
        {
            string nombre = Convert.ToString(dr["Name"]);
            list.Add(nombre);
        }
    }
    return list;
}


Modificar datos con una consulta SQL

En este ejemplo modificaremos la fecha de nacimiento de un empleado. Primero obtenemos el objeto DataBase, luego ejecutamos el metodo ExecuteNonQuery indicando con el primer parametro que es una consulta SQL a diferencia de un Procedimiento Almacenado y como segundo parametro la sql UPDATE.
El metodo ExecuteNonQuery devuelve un entero que representa el numero de filas modificadas, este dato sirve para determinar si efectivamente la modificacion se realizo y detectar posibles problemas de concurrencia. En este caso si no se modifico ninguna fila lanzamos una Excepcion.

public void UpdateFechaNacimiento(int id, DateTime fechaNacimiento)
{
    Database dataBase = DatabaseFactory.CreateDatabase("AdventureWorks");
    string sql = "UPDATE HumanResources.Employee SET BirthDate=" + fechaNacimiento + " WHERE Id=" + id;
    int res = dataBase.ExecuteNonQuery(CommandType.Text, sql);
    if (res == 0)
        throw new ArgumentException("Id no encontrado");
}