Configuración del proyecto:
En el proyecto debemos hacer referencia a las siguientes dll:
Microsoft.Practices.EnterpriseLibrary.Data.dll
Microsoft.Practices.EnterpriseLibrary.Common.dll
Además debe estar en el mismo directorio:
Microsoft.Practices.ObjectBuilder2.dll
Microsoft.Practices.Unity.dll
En el archivo de configuración debemos tener agregada la cadena de conexion. Ej:
<connectionStrings>
<add name="Noanet.Cenit" providerName="System.Data.SqlClient" connectionString="Data Source=localhost;Initial Catalog=Noanet.Cenit;Integrated Security=SSPI;"/>
</connectionStrings>
Aca podemos ver que se define un nombre, el provider y la cadena de conexion en si. El provider varia de acuerdo al motor de base de datos al cual nos queremos conectar (Informix, Oracle, Mysql, MsSql, Odbc, etc)
Programación:
El espacio de nombres a usar será Microsoft.Practices.EnterpriseLibrary.Data.
Para comenzar a usar la conexion solo debemos tener un objeto del tipo Database creado con la instruccion new Database("nombre de la cadena de conexion");
Los siguientes son los métodos mas usados del objeto Database:
AddInParameter
GetSqlStringCommand
ExecuteNonQuery
ExecuteReader
ExecuteScalar
Generalmente usamos el objeto DbCommand para el manejo de los metodos antes mencionados.
Un ejemplo de uso correcto es el siguiente:
using Microsoft.Practices.EnterpriseLibrary.Data;
public class DataAccess
{
private Database _db;
private static readonly ILog _log = LogManager.GetLogger(typeof(DataAccess));
public DataAccess()
{
_db = new Database("Noanet.Cenit");
}
public void SaveProduct(Product product)
{
DbCommand = null;
try
{
command = _db.GetSqlStringCommand("INSERT INTO Products (Name, Price, Provider) VALUES (@p1, @p2, @p3)");
_db.AddInParameter(command, "p1", DbType.String, product.Name);
_db.AddInParameter(command, "p2", DbType.Double, product.Price);
_db.AddInParameter(command, "p3", DbType.String, product.Provider);
_db.ExecuteNonQuery( command );
}
catch(Exception ex)
{
_log.Error("GetProductsByProvider", ex);
throw;
}
finally
{
if (command != null) command .Dispose();
}
}
public double GetProducPrice(int id)
{
DbCommand = null;
try
{
command = _db.GetSqlStringCommand("SELECT Price FROM Products WHERE Price = @p1");
_db.AddInParameter(command, "p1", DbType.Int32, id);
double price = Convert.ToDouble( _db.ExecuteScalar( command ) );
return price;
}
catch(Exception ex)
{
_log.Error("GetProductsByProvider", ex);
throw;
}
finally
{
if (command != null) command .Dispose();
}
}
public IList<Product> GetProductsByProvider(string provider)
{
DbCommand command = null;
IDataReader reader = null;
try
{
command = _db.GetSqlStringCommand("SELECT Id, Name, Price FROM Products WHERE Provider = @p1");
_db.AddInParameter(command, "p1", DbType.String, provider);
reader = _db.ExecuteReader(command);
IList<Product> products = new List<Product>();
while(reader.Read())
{
Product product = new Product();
product.Id = reader.GetInt32(0);
product.Name = reader.GetString(1);
product.Price = reader.GetDouble(2);
product.Provider = provider;
products.Add( product );
}
return products;
}
catch(Exception ex)
{
_log.Error("GetProductsByProvider", ex);
throw;
}
finally
{
if (reader != null) reader.Dispose();
if (command != null) command .Dispose();
}
}
}
Observaciones:
Siempre debemos hacer un Dispose() tanto del DbCommand como del IDataReader. Esto es obligatorio, ya que si no lo hacemos vamos a tener problemas con el pool de conexiones ya que no se liberan sin esto.
Para pasar parametros en la consulta siempre debemos usar AddInParameter
Tratar de usar el bloque finally para una codificación clara.