La filosofía de desarrollo es la misma que si estuviéramos utilizando un único origen de datos, por ejemplo SQL Server, en este caso utilizaríamos los métodos SqlConnection, SqlCommand, etc … Pero en lugar de utilizar un proveedor especifico para cada origen de datos vamos a utilizar un proveedor genérico que va a servir para todos. Utilizaremos los interfaces definidos en el espacio de nombre System.Data:
- IDbConnection
- IDbCommand
- IDataAdapter
- IDataParameter.
A través de los cuales podremos asociar cualquier proveedor de acceso a datos especifico, como por ejemplo SQL Server.
IDbConnection
Es el interface que va a representar una conexión abierta con un origen de datos.
Clases que implementan IDbConnection:
- OdbcConnection
- OleDbConnection
- OracleConnection
- SqlConnection
- SqlCeConnection
En el momento de abrir nuestra conexión a tenemos que asociarlo al proveedor de datos que queremos utilizar. Un método para realizar la conexión quedaría de la siguiente forma:
private static IDbConnection GetConnection() {
IDbConnection objectConnection = new SqlConnection(_ConnectionString);
objectConnection.Open();
return (objectConnection);
}
Si ahora queremos ampliar el abanico de proveedores solo necesitamos pasar el tipo de proveedor por parámetros y añadir una sentencia switch, que diferencie el tipo de proveedor:
private static IDbConnection GetConnection(string providerType) {
IDbConnection objectConnection;
switch (providerType) {
case "Provider_SqlClient":
objectConnection = new SqlConnection(_ConnectionString);
break;
case "Provider_OleDb":
objectConnection = new OleDbConnection(_ConnectionString);
break;
case "Provider_Odbc":
objectConnection = new OdbcConnection(_ConnectionString);
break;
default:
throw(new Exception("Tipo invalido de proveedor"));
}
objectConnection.Open();
return (objectConnection);
}
IDbCommand
Representa la ejecución de un comando.
Clases que implementan IDbCommand:
- ObdcCommand
- OleDbCommand
- OracleCommand
- SqlCommand
- SqlCeCommand
Igual que sucede con IDbConnection debemos asociarlo al proveedor de datos correspondiente.
private static IDbCommand CreateCommand(string providerType) {
IDbCommand objectCmd;
switch (providerType) {
case "Provider_SqlClient":
objectCmd = new SqlCommand();
break;
case "Provider_OleDb":
objectCmd = new OleDbCommand();
break;
case "Provider_Odbc":
objectCmd = new OdbcCommand();
break;
default:
throw(new Exception("Invalid provider type"));
}
return (objectCmd);
}
IDataAdapter
Representa un DataAdapter, un cojunto de resultados que podemos utilizar y asociar a un DataSet.
Clases que implementan IDataAdapter:
Igual que sucede con los anteriores tenemos que asociar el IDataAdapter con el correspondiente proveedor de acceso que utilicemos.
IDataAdapter da;
switch (providerType) {
case "Provider_SqlClient":
da = new SqlDataAdapter((SqlCommand)cmd);
break;
case "Provider_OleDb":
da = new OleDbDataAdapter((OleDbCommand)cmd);
break;
case "Provider_Odbc":
da = new OdbcDataAdapter((OdbcCommand)cmd);
break;
default:
throw(new Exception("Invalid provider type"));
}
Generis Data Access
Como podéis comprobar a través de estos interfaces genéricos podemos crear clases de acceso a datos que nos sirvan para cualquier proveedor.
En el ejemplo que viene con el artículo hay una clase llamada GenericDataAccess.cs. A través de esta clase tenéis los métodos básicos para conectar y obtener un conjunto de resultados con los proveedores de acceso a datos.
Definimos las contantes donde especificamos los proveedores que vamos a utilizar.
public const string PROVIDER_SQLCLIENT = "Provider_SqlClient";
public const string PROVIDER_OLEDB = "Provider_OleDb";
public const string PROVIDER_ODBC = "Provider_Odbc";
private static string _sqlQuery = string.Empty;
private static string _ConnectionString = string.Empty;
//
public static string SetConnectionString {
set {
_ConnectionString = value;
}
}
//
public static string SetSqlQuery {
set {
_sqlQuery = value;
}
}
private static IDbConnection GetConnection(string providerType) {
// Código explicado en el articulo
}
private static IDbCommand CreateCommand(string providerType) {
// Código explicado en el articulo
}
public static DataSet ExecuteDataset(string providerType) {
//
// Creamos una conexión
IDbConnection connection = GetConnection(providerType);
// Creamos un comando
IDbCommand cmd = CreateCommand(providerType);
//
// Creamos un DataAdpater genérico y lo asignamos a tipo de //proveedor
//
IDataAdapter da;
switch (providerType) {
case "Provider_SqlClient":
da = new SqlDataAdapter((SqlCommand)cmd);
break;
case "Provider_OleDb":
da = new OleDbDataAdapter((OleDbCommand)cmd);
break;
case "Provider_Odbc":
da = new OdbcDataAdapter((OdbcCommand)cmd);
break;
default:
throw(new Exception("Invalid provider type"));
}
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = _sqlQuery;
DataSet ds = new DataSet();
da.Fill(ds);
//
connection.Close();
return ds;
}
El código fuente que acompaña al articulo, a parte de la clase de acceso a datos, contiene un ejemplo ejecutando un DataGrid con tres orígenes de datos diferentes.
Enlaces relacionadas:
Codigo fuente del artículo
Saludos
Alex