Trasteando en un dataset: seguimos jugando con valores timestamp

Hace unas semanas hablé de usar valores timestamp para controlar la versión del registro de cara a controlar a su vez los problemas de concurrencia, para actualizar datos, etc. Hoy voy a dar un posible uso a todo eso, usando dataset tipados. Vamos a trabajar con una tabla de ejemplo. Supongamos que:

  1. La tabla en cuestión tiene definida una columna, Control, del tipo timestamp.

  2. En el TableAdapter correspondiente hemos añadido dos consultas: una que nos recupera el MAX(Control) de la tabla (el valor más alto de control) y otra que nos devuelve las filas actualizadas desde que obtuvimos ese MAX(Control), o sea, aquellas cuyo valor timestamp sea mayor que el que tenemos guardado.

Con esto ya hecho, lo siguiente podría ser guardar ese valor de control que hemos obtenido de la base de datos. El mejor sitio, la misma DataTable.

Partial Class MaterialDataTable
    Private _MiVersion As Byte()
    Public Property NumVersion() As Byte()
        Get
            Return _MiVersion
        End Get
        Set(ByVal value As Byte())
            _MiVersion = value
        End Set
    End Property
End Class

Tenemos dos métodos Fill, el general y el que carga las filas actualizadas. Estaría bien saber cuándo usar uno u otro. ¿Quizás una propiedad Actualizar en el mismo DataTable que nos lo indique?

Private _Actualizar As Boolean = False
''' <summary>
''' Indica si hay que actualizar la datatable usando el valor del 
''' timestamp o bien cargarla entera en una operación de lectura
''' </summary>
Public Property Actualizar() As Boolean
    Get
        Return Me._Actualizar
    End Get
    Set(ByVal value As Boolean)
        Me._Actualizar = value
    End Set
End Property

¿Por qué guardar esta opción? En mi caso, porque tengo un método llamado LeerDatos se limita a llenar el DataSet que le mandan con lo que devuelve el (o los) TableAdapter. Bueno, y a abrir y cerrar la conexión si es necesario, controlar las excepciones y alguna que otra cosa. Y así me ahorro el tener dos métodos que hagan lo mismo, uno para la lectura general y otro para los valores actualizados (o, si seguimos aumentando, uno para cada consulta). También podría tener el valor de Actualizar aparte y pasarlo como parámetro, pero como es un valor que atañe únicamente al DataTable, mejor que vaya con él.

También podemos ahorrar a LeerDatos el tener que discriminar entre un método Fill u otro y añadir un método en el TableAdapter que se encargue de ello.

Namespace MaterialDataSetTableAdapters
    Partial Class MaterialTableAdapter
        Public Function LeerMaterial(ByVal dtMaterial As  _
            MaterialDataSet.MaterialDataTable) As Integer
            Dim Result As Integer
            Try
                If dtMaterial.Actualizar = True Then
                    Result = Me.FillActualizados(dtMaterial, _
                    dtMaterial.NumVersion)
                Else
                    Result = Me.Fill(dtMaterial)
                End If
                dtMaterial.NumVersion = Me.TimestampActual
            Catch ex As Exception
                Throw ex
            End Try
            Return Result
        End Function
    End Class
End Namespace

El uso que le quiero dar a esto es el siguiente: tengo mi DataSet en memoria. En un momento dado, quiero conectarme a la base de datos, traer los datos actualizados, y sólo esos, y combinarlos con los que ya tengo. Para combinarlos usaré el método Merge que trae el propio DataSet. Ah, cachis, lo que pasa es que así tengo que hacerlo en dos pasos, primero el Merge y luego pasarle el nuevo valor de control. Podría sobrecargar el método Merge para que me haga eso de un tirón, ¿no?

Public Overloads Sub Merge(ByVal dsMaterial As MaterialDataSet)
    Try
        MyBase.Merge(dsMaterial)
        Me.Material.Actualizar = False
        Me.Material.NumVersion = dsMaterial.Material.NumVersion
    Catch ex As Exception
        Throw ex
    End Try
End Sub

En fin, probando cositas y dándole juego a los datasets.

Deja un comentario