.NET Chronicles

Temas relacionados con el desarrollo de aplicaciones con .NET

Octavio Telis

Arquitectura – Definición de un Data Access Component (con un ejemplo) Parte 2

Hola qué tal?

Bueno, pues continuando con la segunda parte de la construcción de un Data Access Component con ejemplos, en esta ocasión hablaremos de la manera en que se guarda, salva, modifica o borra la información a través de un componente DAC.

Quiero reiterar que un componente DAC, será exclusivo de un objeto de la base de datos, en general una tabla. Teniendo en cuenta esto, crearemos algunos métodos para las tareas de salvar y borrar, que serán exclusivas para el objeto de la base de datos con el que se corresponde el DAC. No olvidemos que el DAC es la abstracción del objeto de la base de datos, en nuestro caso, una abstracción de la tabla y como tal debe tener la capacidad de mostrar los elementos de un registro dado y la capacidad de realizar tareas con este hacia la base de datos.

En artículo anterior vimos como implementar la abstracción de lo campos de la tabla en propiedades de la clase, cómo se construye la clase con los valores predeterminados y cómo se construye con un valor de identificación de registro.

Ahora veamos cómo salvar un registro, es simple y tiene la inteligencia suficiente para ser un solo método para la inserción y para la actualización de un registro.

Como habrán notado, en el bloque de declaración de campo, existe una variable boleana denominada nuevo, esta variable se asigna dependiendo de la manera en que se construye el objeto, si el objeto se construye sin un identificador de registro, la variable será true, si se inicializa con un identificador de registro que devuelva un registro válido, entonces será false, pero si el identificador no devuelve un registro válido, entonces será true. En pocas palabras, la variable nuevo sirve para identificar el registro como uno nuevo o como uno existente en la base de datos.

Tomando en cuenta este criterio, el método salvar elegirá entre dos opciones, la primera es insertar un nuevo registro, para el caso de nuevo = true, y el segundo será realizar una actualización (update)  para el caso nuevo = false.

Veamos pues cómo se conforma el método Salvar():

VB

Private Sub InitializeParameters()

 

    cmd.Parameters.Clear()

    cmd.Parameters.Add( _

        “@ClaveTipoProducto”, _

        SqlDbType.VarChar, 10).Value = _ClaveTipoProducto

    cmd.Parameters.Add( _

        “@Descripcion”, _

        SqlDbType.VarChar, 150).Value = _Descripcion

 

    If _Nuevo Then

        cmd.Parameters.Add( _

            “@SP_OPCION”, _

            SqlDbType.TinyInt).Value = 1

        cmd.Parameters.Add( _

            “@IdTipoProducto”, _

            SqlDbType.Int, 4).Direction = ParameterDirection.Output

    Else

        cmd.Parameters.Add( _

            “@SP_OPCION”, _

            SqlDbType.TinyInt).Value = 2

        cmd.Parameters.Add( _

            “@IdTipoProducto”, _

            SqlDbType.Int, 4).Value = _IdTipoProducto

    End If

End Sub

 

 

Public Function Salvar() As Integer

    Dim Res As Integer

    InitializeParameters()

 

    Res = MyBase.ExecuteTransaction(cmd)

 

    If _Nuevo AndAlso Res > 0 Then

        Dim resIdTipoProducto As Integer?

        Try

            resIdTipoProducto = _

                DirectCast( _

                    cmd.Parameters(“@IdTipoProducto”).Value, _

                    Integer?)

            _IdTipoProducto = resIdTipoProducto

            _Nuevo = resIdTipoProducto < 0

        Catch ex As Exception

            _IdTipoProducto = -1

            _Nuevo = True

        End Try

    End If

 

    Return Res

 

End Function

C#

private void InitializeParameters()

{

    cmd.Parameters.Clear();

    cmd.Parameters.Add(

        “@ClaveTipoProducto”,

        SqlDbType.VarChar, 10).Value = claveTipoProducto;

    cmd.Parameters.Add(

        “@Descripcion”,

        SqlDbType.VarChar, 150).Value = descripcion;

   

    if (nuevo)

    {

        cmd.Parameters.Add(

            “@SP_OPCION”,

            SqlDbType.TinyInt).Value = 1;

        cmd.Parameters.Add(

            “@IdTipoProducto”,

            SqlDbType.Int, 4).Direction = ParameterDirection.Output;

    }

    else

    {

        cmd.Parameters.Add(

            “@SP_OPCION”,

            SqlDbType.TinyInt).Value = 2;

        cmd.Parameters.Add(

            “@IdTipoProducto”,

            SqlDbType.Int, 4).Value = idTipoProducto;

    }

}

 

public int Salvar()

{

    int Res;

    InitializeParameters();

 

    Res = base.ExecuteTransaction(cmd);

 

    if (nuevo && Res > 0)

    {

        int? _idTipoProducto;

        _idTipoProducto =

            cmd.Parameters[“@IdTipoProducto”].Value as int?;

        idTipoProducto =

            _idTipoProducto == null ? -1 : _idTipoProducto.Value;

        nuevo = _idTipoProducto < 0;

    }

    return Res;

}

Podemos observar que hay un método “colado”, bueno, es el simple encapsulamiento de la inicialización de parámetros que serán pasados al SqlCommand para ser ejecutado. Recordemos que la opción 1 de Stored Procedure es para insertar y que la opción 2 es para actualizar, así pues, se elige con qué parámetro de opción se mandará el SqlCommand al Helper para ser ejecutado.

Otra observación interesante, es la manera en que se recuperará el valor del identificador, ya que al ser automático y variable de retorno del SP, se puede pasar a una variable temporal para asignarla a la variable principal. Cuando esto pasa, si se tuvo éxito al salvar, pasaremos a la clase a nuevo = false.

Pero aún así, se preguntarán, cómo se salvan uno o más tablas dentro de una transacción. Bueno, para poder habilitar esta labor, deberemos proveer el mismo método, pero esta vez, sobrecargado, donde tendremos a un SqlTransactio como parámetro, mismo que pasaremos al DataHelper para ser ejecutado en un mismo contexto. Veamos cómo quedaría:

VB

Public Function Salvar(trn As SqlTransaction) As Integer

    Dim Res As Integer

    InitializeParameters()

 

    Res = MyBase.ExecuteTransaction(cmd,trn)

 

    If _Nuevo AndAlso Res > 0 Then

        Dim resIdTipoProducto As Integer?

        Try

            resIdTipoProducto = _

                DirectCast( _

                    cmd.Parameters(“@IdTipoProducto”).Value, _

                    Integer?)

            _IdTipoProducto = resIdTipoProducto

            _Nuevo = resIdTipoProducto < 0

        Catch ex As Exception

            _IdTipoProducto = -1

            _Nuevo = True

        End Try

    End If

 

    Return Res

End Function

C#

public int Salvar(SqlTransaction trn)

{

    int Res;

    InitializeParameters();

 

    Res = base.ExecuteTransaction(cmd, trn);

 

    if (nuevo && Res > 0)

    {

        int? _idTipoProducto;

        _idTipoProducto =

            cmd.Parameters[“@IdTipoProducto”].Value as int?;

        idTipoProducto =

            _idTipoProducto == null ? -1 : _idTipoProducto.Value;

        nuevo = _idTipoProducto < 0;

    }

    return Res;

}

La única diferencia es que se utiliza el método ExecuteTransaction sobrecargado.

De esta manera ya vemos cómo se salva el registro, la opción de insertar o actualizar depende de la variable ‘nuevo’ que nos indica si el registro existe o no en la base de datos.

El otro método es el de Borra, tendremos dos, uno que borra el registro actual, y otro método para borrar un registro dado, pasando el identificador del mismo.

VB

Public Function Borrar() As Integer

    Dim Res As Integer

    cmd.Parameters.Clear()

    cmd.Parameters.Add( _

        “@SP_OPCION”, _

        SqlDbType.TinyInt).Value = 3

    cmd.Parameters.Add( _

        “@IdTipoProducto”, _

        SqlDbType.Int, 4).Value = IdTipoProducto

    Res = MyBase.ExecuteTransaction(cmd)

    Return Res

End Function

 

Public Function Borrar( _

        ByVal pIdTipoProducto As Integer) As Integer

    Dim Res As Integer

    cmd.Parameters.Clear()

    cmd.Parameters.Add( _

        “@SP_OPCION”, _

        SqlDbType.TinyInt).Value = 3

    cmd.Parameters.Add( _

        “@IdTipoProducto”, _

        SqlDbType.Int, 4).Value = pIdTipoProducto

    Res = MyBase.ExecuteTransaction(cmd)

    Return Res

End Function

C#

public int Borrar()

{

    int Res;

    cmd.Parameters.Clear();

    cmd.Parameters.Add(

        “@SP_OPCION”,

        SqlDbType.TinyInt).Value = 3;

    cmd.Parameters.Add(

        “@IdTipoProducto”,

        SqlDbType.Int, 4).Value = idTipoProducto;

    Res = base.ExecuteTransaction(cmd);

    return Res;

}

 

public int Borrar(int pIdTipoProducto)

{

    int Res;

    cmd.Parameters.Clear();

    cmd.Parameters.Add(

        “@SP_OPCION”,

        SqlDbType.TinyInt).Value = 3;

    cmd.Parameters.Add(

        “@IdTipoProducto”,

        SqlDbType.Int, 4).Value = pIdTipoProducto;

    Res = base.ExecuteTransaction(cmd);

    return Res;

}

Como podrá notarse, el método borrar es simple, y no es más que el llamado de la opción y pasar el identificador del registro que se desea borrar.

Con esto tenemos completo un DAC, o al menos con la funcionalidad básica necesaria para utilizarlo.

El método Salvar transaccional, solo será útil en un componente de negocios, que sí, podremos utilizar en algún momento.

El uso de este componente es directo en la interfaz de usuario, solo debemos agregar la referencia correspondiente al proyecto de DLL que lo contiene. En el siguiente artículo sobre el tema, veremos de una manera rápida el uso de este componente y cómo simplifica mucho la codificación de la interfaz de usuario.

Referencias:

Parte 1: http://msmvps.com/blogs/otelis/archive/2009/09/11/arquitectura-definici-243-n-de-un-data-acces-component-con-un-ejemplo.aspx

Parte 3: http://msmvps.com/blogs/otelis/archive/2010/05/14/arquitectura-definici-243-n-de-un-data-access-component-con-un-ejemplo-parte-3.aspx

Saludos…

Octavio Telis

 

Leave a Reply

Your email address will not be published. Required fields are marked *


*

.NET Chronicles
  • Eventos del Teclado en WPF July 22, 2015
      Hola ¿qué tal? En esta ocasión como como continuidad a lo que previamente había escrito sobre los eventos del teclado en Windows Forms, haré un artículo sobre el uso de los eventos del teclado en WPF, así es en Windows Presentation Foundation. No es desconocido por muchos que el nuevo estándar de desarrollo de […]
  • Programación Orientada a Objetos (Introducción) May 14, 2014
    Hola qué tal… Aquí les dejo este video sobre la programación orientada a objetos, a manera de preámbulo a los siguientes videos, con las bases de la programación en C# y otra línea con algunas utilerías. Saludos… Octavio Telis
  • Capítulo piloto del la versión en video de .NET Chronicles May 6, 2014
    Hola qué tal??? Pues en esta ocasión estoy compartiendo con ustedes la liga de un video piloto, con el que pretendo comunicar un poco más sobre las tecnologías .NET y los lenguajes de Programación. En esta ocasión será con la presentación de C#, en un capitulo titulado “Te presento a C#”, espero que sea de […]
  • Validación de datos de entrada con enlace a datos en WPF May 27, 2012
    Tweet Hola, qué tal. Ya que he venido hablando del enlace a datos en WPF en las publicaciones anteriores, bien convendría considerar el uso del Binding para validar datos, hemos tocado ya algunos puntos necesarios para escribir esta funcionalidad. En las publicaciones anteriores vimos ya como enlazar los datos, además, cómo convertir los datos, ahora, […]
  • Uso de la propiedad Visibility con valores booleanos en WPF May 25, 2012
    Tweet    Hola que tal. En esta ocasión quiero compartir con ustedes una manera para utilizar la propiedad Visibility con un valor bool. Te preguntarás “¿Y qué sentido tiene eso?”, bien, el detalles está en que en ocasiones se requiere que la visibilidad de un control de la interfaz de usuario responda a un valor […]
  • Conversión de Valores con Enlace a Datos May 24, 2012
    Tweet     Hola que tal. En el diseño de aplicaciones con WPF tendremos muchas ventajas en cuanto a la interfaz de usuario se refiere, dado que es un modelo muy flexible, nos permite dar formato y estilo a la apariencia de la interfaz de usuario, logrando aplicaciones más agradables, vistosas y que mejoran por mucho […]
  • Mostrar archivos de imagen en WPF utilizando enlace a datos. May 23, 2012
    Tweet Holal Qué tal. Continuando con el ejemplo del post anterior (http://bit.ly/oh0m9k), referente al manejo de imágenes en WPF, ejemplificaremos el manejo de las imágenes de la misma manera pero, esta vez, utilizando enlace a datos y la clase Binding. Antes, tenemos que hablar un poco de lo que es el enlace a datos con […]
  • Mostrar archivos de imagen en WPF August 26, 2011
    Hola Qué Tal… En esta ocasión quiero comenzar una serie de artículos sobre el manejo de archivos de imágenes con .NET. En esta primera parte voy a tratar la manera de cargar un archivo de imagen en un contenedor de imagen, en este caso usaré WPF y el control Image que viene incluido en el […]
  • Comparar dos DataTables según sus DataRows August 23, 2011
    Hola que tal. En ocasiones es necesario comparar el contenido de dos DataTable para determinar qué registros (DataRow) están en una y en otra no. Supongamos tenemos dos DataTable; dt1 y dt2, ambas con el mismo esquema. La tabla dt2 contiene más registros que la taba dt1, por lo que deseamos saber qué registros de […]
  • Arquitectura – Definición de un Data Access Component (con un ejemplo) Parte 3 May 14, 2010
    Hola Qué Tal? En esta ocasión, no he dejado pasar tanto tiempo para terminar la trilogía del uso de Data Access Component con un ejemplo. Bien, pues en este artículo veremos el uso del componente ya creado, cómo extenderemos la funcionalidad del componente y cómo lo aplicamos en la interfaz de usuario. Primeramente, debemos crear […]