Mostrando entradas con la etiqueta MS Access. Mostrar todas las entradas
Mostrando entradas con la etiqueta MS Access. Mostrar todas las entradas

domingo, 29 de noviembre de 2009

C# – ADO.NET – Parte 4 – Actualización Información Ms Access

 

Introducción

Este articulo intenta brindar un ejemplo practico de como hacer uso de los objetos de ADO.NET para poder manipular la información de la base de datos, en este caso será de Ms Access.

Gran parte de la explicación se ha realizado en artículos previos

C# – ADO.NET – Parte 3 – Actualización Información Sql Server

que si bien tratan otra base de datos, se vera que salvo algunos pequeños detalles es prácticamente idéntico.

Es por eso que a medida que se vaya analizando el código del articulo es recomendable darle un vistazo al link de la Parte 3 del articulo, este contendrá detalles mas precisos sobre algunos aspectos utilizados.

 

1 – Creación nueva entidad (Insert)

En este código encontraran también el método Save() el cual será el encargado de determinar si es necesario insertar el registro o simplemente actualizarlos

public static ContactoEntity Save(ContactoEntity contacto)
{

    if (string.IsNullOrEmpty(contacto.Nombre))
        throw new BusinessException(Messages.MSG1002);

    if (string.IsNullOrEmpty(contacto.Apellido))
        throw new BusinessException(Messages.MSG1003);

    if (Exists(contacto))
        return Update(contacto);
    else
        return Insert(contacto);
}

Si se analiza el código veras que la funcionalidad que determina si existe la entidad es idéntica a como se programaría cuando se hace uso de Sql Server, el único cambio radica en que se utiliza los objeto de OleDb

private static bool Exists(ContactoEntity contacto)
{
    if (contacto == null)
        throw new BusinessException(Messages.ERR1001); 

    return Exists(contacto.IdContacto);
}

private static bool Exists(int Id)
{
    string sql = @"SELECT COUNT(*)
                      FROM Contacto
                      WHERE IdContacto = @Id";


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

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

        conn.Open();

        int count = Convert.ToInt32(command.ExecuteScalar());

        if (count == 0)
            return false;
        else
            return true;
        
    }
}

al igual que el ejemplo del link relacionado, se hace uso de ExecuteScalar, el cual devolverá simplemente la primer columna de la primer fila de la consulta.

LA funcionalidad que inserta tiene un pequeño detalles que hay que aclararlo ya que puede presentarse problemas en otras circunstancias.

Este se presenta al declarar el parámetro de fecha de nacimiento (líneas 28-30), se vera que se crea una variable del tipo OleDbParameter en donde se define el tipo de dato puntualmente.

Esto debe ser así ya que el método AddWithValue() no puede determinar para este tipo de dato cual es el correcto, cuando se le pasarle un objeto del tipo DataTime de .net, es por eso que hay que definirlo OleDbType.Date, y de esta forma funciona perfectamente.

 

private static ContactoEntity Insert(ContactoEntity contacto)
{
    string sql = @"INSERT INTO Contacto (IdContacto
                          ,Nombre
                          ,Apellido
                          ,FechaNacimiento
                          ,Localidad
                          ,Calle
                          ,Numero)
                      VALUES (@Id, 
                            @Nombre, 
                            @Apellido, 
                            @FechaNacimiento, 
                            @Localidad, 
                            @Calle, 
                            @Numero)";


    using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {
        int NextId = MaxId() + 1;

        OleDbCommand command = new OleDbCommand(sql, conn);
        command.Parameters.AddWithValue("Id", NextId);
        command.Parameters.AddWithValue("Nombre", contacto.Nombre);
        command.Parameters.AddWithValue("Apellido", contacto.Apellido);
        
        OleDbParameter param = new OleDbParameter("FechaNacimiento", OleDbType.Date);
        param.Value = contacto.FechaNacimiento;
        command.Parameters.Add(param);
        
        command.Parameters.AddWithValue("Localidad", string.IsNullOrEmpty(contacto.Localidad) ? (object)DBNull.Value : contacto.Localidad);
        command.Parameters.AddWithValue("Calle", string.IsNullOrEmpty(contacto.Calle) ? (object)DBNull.Value : contacto.Calle);
        command.Parameters.AddWithValue("Numero", contacto.Numero.HasValue ? contacto.Numero : (object)DBNull.Value );

        conn.Open();

        command.ExecuteNonQuery();

        contacto.IdContacto = NextId;

        return contacto;

    }
}

También se veras que la función MaxId() que permite recuperar el ultimo id ingresado no sufre cambio alguno con respecto a utilizado en una base de datos Sql Server

private static int MaxId()
{
    string sql = @"SELECT MAX(IdContacto)
                      FROM Contacto";


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

        OleDbCommand command = new OleDbCommand(sql, conn);

        conn.Open();

        return Convert.ToInt32(command.ExecuteScalar());

    }
}

2 – Actualización de la entidad (Update)

En la operación de actualización hay que remarcar dos puntos que son importantes y generan cambio con respecto a su equivalente en Sql Server

Uno al igual que como sucedió en la funcionalidad de Insert, es necesario definir el tipo de dato explicito para la fecha de nacimiento.

El segundo aspecto se refiere a que si bien hasta ahora pensábamos que los nombres de los parámetros guardaban una conexión, bajo la operación del actualización nos damos cuenta que no es tan así.

Es por ello que se notara que la creación de parámetros en este caso el “Id” ha sido declarado al final del resto, mientras que en si equivalente para Sql Server podría haber sido declarado en cualquier posición.

Esto marca un punto importante durante la actualización y es que el nombre sirve para tener una referencia a que parámetro estamos asignando el valor, pero para el provider de base de datos OleDb, lo que importa es la posición del parámetro en colección de Parameters.

Si en este código se declarar el parámetro “Id” en primer lugar la actualización no se realizaría adecuadamente.

private static ContactoEntity Update(ContactoEntity contacto)
{

    string sql = @"UPDATE Contacto SET 
                          Nombre = @Nombre
                          ,Apellido = @Apellido
                          ,FechaNacimiento = @FechaNacimiento
                          ,Localidad =  @Localidad
                          ,Calle =  @Calle
                          ,Numero = @Numero
                    WHERE IdContacto = @Id";


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

        OleDbCommand command = new OleDbCommand(sql, conn);
        
        command.Parameters.AddWithValue("Nombre", contacto.Nombre);
        command.Parameters.AddWithValue("Apellido", contacto.Apellido);

        OleDbParameter param = new OleDbParameter("FechaNacimiento", OleDbType.Date);
        param.Value = contacto.FechaNacimiento;
        command.Parameters.Add(param);

        command.Parameters.AddWithValue("Localidad", string.IsNullOrEmpty(contacto.Localidad) ? (object)DBNull.Value : contacto.Localidad);
        command.Parameters.AddWithValue("Calle", string.IsNullOrEmpty(contacto.Calle) ? (object)DBNull.Value : contacto.Calle);
        command.Parameters.AddWithValue("Numero", contacto.Numero.HasValue ? contacto.Numero : (object)DBNull.Value);
        
        command.Parameters.AddWithValue("Id", contacto.IdContacto);

        conn.Open();

        int rows = command.ExecuteNonQuery();

        return contacto;

    }
}

3 – Eliminación de la entidad (Delete)

Esta operación no sufre cambio alguno con respecto a su equivalente en Sql Server, salvo los objetos de ado.net utilizados.

 

public static void Delete(int Id)
{
    string sql = @"DELETE FROM Contacto 
                   WHERE [IdContacto] = @Id";


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

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

        conn.Open();

        command.ExecuteNonQuery();

    }
}

 

[C#]
[VB.NET]

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]