domingo, 22 de noviembre de 2009

[ADO.NET] Recuperar Información MS Access

 

Introducción


Con este ejemplo intento demostrar como con algunos simples cambios se puede utilizar ado.net de una forma similar tanto si se accede a sql server como si es Access la base de datos utilizada

Este post esta adaptado de la primera parte

C# – ADO.NET - Recuperar Información Sql Server – Parte 1

por lo tanto muchas de las explicaciones serán obviadas ya que los pasos son idénticos para ambos métodos.

Ante cualquier duda en los paso necesario para utilizar ado.net se podrá recurrir al primer articulo ya que la forma de codificar es idéntica para Sql Server y Access

En los ejemplos se observara que la técnica puede aplicarse exactamente de la misma forma, solo se ha cambiado los nombre de los objetos utilizados, por ejemplo en lugar de ser SqlConnection se utilizaría el OleDbConnection, y así con el resto de los objetos a utilizar.

 

1 - Recuperar un conjunto de datos (DataReader)


En este se recorre mediante el objeto OleDbDataReader los datos recuperados mediante la ejecución de la consulta.

public static List<ContactoEntity> GetAll()
{
    string sql = @"SELECT [IdContacto]
                          ,[Nombre]
                          ,[Apellido]
                          ,[FechaNacimiento]
                          ,[Localidad]
                          ,[Calle]
                          ,[Numero]
                      FROM Contacto";

    List<ContactoEntity> list = new List<ContactoEntity>();

    using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {

        OleDbCommand command = new OleDbCommand(sql, conn);

        conn.Open();

        OleDbDataReader reader = command.ExecuteReader();

        while (reader.Read())
        {
            list.Add(LoadContacto(reader));
        }

        return list;
    }


}

Como se observa el método utilizado para crear la entidad se mantiene exactamente igual, ya que al usarse una interfaz del tipo IDataReader, esta mantiene compatibilidad tanto si proviene de Sql server, como Access

private static ContactoEntity LoadContacto(IDataReader reader)
{
    ContactoEntity contacto = new ContactoEntity();

    contacto.IdContacto = Convert.ToInt32(reader["IdContacto"]);

    contacto.Nombre = Convert.ToString(reader["Nombre"]);
    contacto.Apellido = Convert.ToString(reader["Apellido"]);

    contacto.FechaNacimiento = Convert.ToDateTime(reader["FechaNacimiento"]);

    contacto.Localidad = Convert.ToString(reader["Localidad"]);
    contacto.Calle = Convert.ToString(reader["Calle"]);
    contacto.Numero = Convert.ToInt16(reader["Numero"]);


    return contacto;
}

2- Recuperar un conjunto de datos (DataSet)


Al igual que el ejemplo planteado en Sql Server, este utiliza un DataSet Tipado es mas, como el DataSet es independiente de la tecnología utilizada en el acceso a los datos se pudo reutilizar el del ejemplo anterior

public static dtoContacto GetAllFromDataSet()
{
    string sql = @"SELECT [IdContacto]
                          ,[Nombre]
                          ,[Apellido]
                          ,[FechaNacimiento]
                          ,[Localidad]
                          ,[Calle]
                          ,[Numero]
                      FROM Contacto";

    using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {

        OleDbCommand command = new OleDbCommand(sql, conn);

        OleDbDataAdapter da = new OleDbDataAdapter(command);

        dtoContacto contactos = new dtoContacto();

        da.Fill(contactos, "Contacto");

        return contactos;
    }


}

3 – Recuperar un solo registro (DataReader)


Debe remarcarse en esta parte del ejemplo que Access también permite el uso de parámetros en sus consultas, en este caso al usarse el proveedor: Microsoft.Jet.OLEDB.4.0, los parámetros siguen teniendo el mismo formato que Sql Server, o sea hacen uso de @param, (en donde param es el nombre del parámetro), pero si se utiliza algún otro proveedor de acceso a datos para OleDb puede que esto cambie, y se necesite hacer uso del signo ?, para especificar la posición del mismo.

public static ContactoEntity GetById(int Id)
{
    string sql = @"SELECT [IdContacto]
                          ,[Nombre]
                          ,[Apellido]
                          ,[FechaNacimiento]
                          ,[Localidad]
                          ,[Calle]
                          ,[Numero]
                      FROM Contacto
                      WHERE IdContacto = @Id";

    ContactoEntity product = null;

    using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {

        OleDbCommand command = new OleDbCommand(sql, conn);
        command.Parameters.AddWithValue("Id", Id);

        conn.Open();

        OleDbDataReader reader = command.ExecuteReader();

        if (reader.Read())
        {
            product = LoadContacto(reader);
        }

        return product;
    }
}

4 – Recuperar un solo registro (DataSet)


Aquí hay que resaltar el cambio de  enumerado utilizado para definir el tipo de datos del parámetro, siendo el OleDbType

 

public static dtoContacto.ContactoRow GetByIdFromDataSet(int Id)
{
    string sql = @"SELECT [IdContacto]
                          ,[Nombre]
                          ,[Apellido]
                          ,[FechaNacimiento]
                          ,[Localidad]
                          ,[Calle]
                          ,[Numero]
                      FROM Contacto
                      WHERE IdContacto = @Id";

    using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {

        OleDbCommand command = new OleDbCommand(sql, conn);

        OleDbParameter param = new OleDbParameter("Id", OleDbType.Integer);
        param.Value = Id;
        command.Parameters.Add(param);

        OleDbDataAdapter da = new OleDbDataAdapter(command);

        dtoContacto contactos = new dtoContacto();

        da.Fill(contactos, "Contacto");

        if (contactos.Contacto.Rows.Count > 0)
            return contactos.Contacto.Rows[0] as dtoContacto.ContactoRow;
        else
            return null;
    }
}

Conclusión

Una vez se comprenda el concepto general de los objetos implicados en las consultas a las base de datos, las diferencias son mínimas, conociendo los objetos de ADO.NET básicos se puede consultar cualquier base de datos con pequeños cambios y lo aprendido para trabajar con una base de datos especifica pueden aplicarse al resto.

 

[C#] 
[VB.NET] 

11 comentarios:

  1. Sr. Alejandro, sería muy bueno escribiera ejemplos de uso de operaciones grud usando tableadapter. Gracias.

    ResponderEliminar
  2. hola Marlon

    El tema es que soy mas de desarrollo en capas y funciones en donde trato controlar cada aspecto de desarrollo.

    Si bien conozco el TableAdapter y todo lo que implica el uso de DataSet Tipados, no suelo usarlo mucho en los desarrollos que realizo, mas que nada porque no se adaptan bien en una arquitectura y crean codigo que uno no puede controlar.

    Vere si en algun momento me hago un rato y creo un articulo sobre el tema.

    saludos

    ResponderEliminar
  3. Benas tardes, Amigo Leandro, he visto alguna información sobre esto y no llego a la solución, de todos modos se lo planteo: Tengo vs2010 professional, trabajando con c sharp. He instalado Crystal 2010 y puedo crear el reporte mas no me aparece la pestaña de cristal en la barra de herramientas, por lo que no puedo usar el CrystalReporviewer. Gracias.

    ResponderEliminar
  4. Olive indicar que VS 2010 profesional en ingles

    ResponderEliminar
  5. Leandro, se que no tiene que ver con el ejemplo pero tengo una consulta. necesito generar en access una secuencia de numeros como en oracle, se puede hacer? no me sirve el autonumerico dado que se van a generar desde diferentes puestos al mismo tiempo y no importa si no son correlativos ya que algunos usuarios no confirmar su registro. gracias

    ResponderEliminar
  6. hola ariel

    hasta donde conozco de Oracle de Secuential genera un correctaltivo identico al autonumerico (identity) que puede usar en Ms Access

    que lo generes de varios lugares no afecta ya que siempre sera incremental

    lo de confirmar los registros no lo entendi, sino conforman no se les genera ningun id por lo que simplemente seria como sino hicierna nada, el id solo se genera si se confirma que seria cuando se envia a persistir

    Nota: no analizaste usar Sql Server, aunque sea en su version Express, digo para algo distribuido Ms Access como que la verdad no recomendaria

    saludos

    ResponderEliminar
  7. creo el link de descarga del proyecto de acces se cayó

    ResponderEliminar
  8. hola JHON

    ya se encuentra actualizado

    saludos

    ResponderEliminar
  9. buenas señor leandro tengo un incoveniente me gustaria traer el id de un registro en acces a un textbox pero no encuentro la manera , tengo una sentencia sql que parece funcionar pero al momento de colocar el valor dentro del text me da error

    ResponderEliminar
  10. hola Rainer

    esta algo raro que quieras traer un Id, imagino que habras querido decir que teniendo un Id recuperar la info de los demas campos

    cual es el mensaje de error que obtienes ?
    imagino usas parametros en la query?

    saludos

    ResponderEliminar
  11. Estoy actualmente capacitandome para el uso de Access y me pareció bastante útil tu artículo sobre las técnicas de recuperacion de informacion y los algoritmos para hacerlo. Muchas gracias!

    ResponderEliminar