domingo, 4 de marzo de 2012

Visualizador de relaciones y restricciones en un DataSet

Quizás hoy en día un método extensor de DataSet y DataTable no sea muy popular porque es una tecnología de la que cualquier Geek de pro huye como la peste.

De hecho, hoy en día no tiene mucho sentido seguir utilizando DataSets puesto que tenemos disponibles otras tecnologías de accedo a datos mucho más modernas y mejor preparadas para la batalla, como son cualquier ORM del estilo de Entity Framework e incluso Linq To Sql (también en desuso pero al fin y al cabo también un ORM).

En cualquier caso, el otro día un amigo me comentaba en el correo que conocer la base de ADO.NET nos ayudará a entender mejor todo las nuevas propuestas de acceso a datos de Microsoft que, al final de los finales, siguen tirando por debajo código ADO.NET (es cierto que EF no utiliza DataSets pero al final y al cabo un DataSet es ADO.NET Core, un must-know).

En esta situación y no pudiendo olvidar que tarde o temprano tendremos que volver a tocar código viejo o heredado que utiliza DataSets, he creído oportuno realizar unos métodos extensores que me ayudarán a ver las relaciones y restricciones existentes en un DataSet a través de la ventana de inspección de Visual Studio.

El código de los métodos extensores es el siguiente (perdona que no sea C#, pero estoy seguro de que sabrás encontrar algún traductor en línea para pasar este código de VB a C#).

Module MyDataSetExtensions
    Private Sub DumpUniqueConstraintToHtml(ByVal uc As UniqueConstraint, ByVal dump As StringBuilder)
        dump.Append(String.Format("<p><b>UniqueConstraint {0}</b></p>", uc.ConstraintName))
        dump.Append(String.Format("<p>IsPrimaryKey {0}</p>", uc.IsPrimaryKey))
        dump.Append("<p>Columns</p>")
        dump.Append("<ul>")
        For Each col As DataColumn In uc.Columns
            dump.Append(String.Format("<li>{0}</li>", col.ColumnName))
        Next
        dump.Append("</ul>")
    End Sub
    Private Sub DumpForeignKeyConstraintToHtml(ByVal fkc As ForeignKeyConstraint, ByVal dump As StringBuilder)
        dump.Append(String.Format("<p><b>ForeignKeyConstraint: {0}</b></p>", fkc.ConstraintName))
        dump.Append(String.Format("<p>UpdateRule {0}</p>", fkc.UpdateRule.ToString()))
        dump.Append(String.Format("<p>DeleteRule {0}</p>", fkc.DeleteRule.ToString()))
        dump.Append(String.Format("<p>AcceptRejectRule {0}</p>", fkc.AcceptRejectRule.ToString()))
        dump.Append(String.Format("<p>RelatedTable {0}</p>", fkc.RelatedTable.TableName))
        dump.Append("<p>RelatedColumns</p>")
        dump.Append("<ul>")
        For Each col As DataColumn In fkc.RelatedColumns
            dump.Append(String.Format("<li>{0}</li>", col.ColumnName))
        Next
        dump.Append("</ul>")
        dump.Append("<p>Columns</p>")
        dump.Append("<ul>")
        For Each col As DataColumn In fkc.Columns
            dump.Append(String.Format("<li>{0}</li>", col.ColumnName))
        Next
        dump.Append("</ul>")
    End Sub
    Private Function GetHtmlStyle() As String
        Return "p, ul, li { margin-bottom: 2px; margin-top: 2px; }"
    End Function
    <System.Runtime.CompilerServices.Extension()> _
    Public Function DumpConstraintsToHtml(ByVal table As DataTable) As String
        Dim dump As New StringBuilder
        dump.Append(String.Format("<style>{0}</style>", GetHtmlStyle()))
        dump.Append(String.Format("<p>TableName {0}</p>", table.TableName))
        dump.Append(String.Format("<p>Constraints {0}</p>", table.Constraints.Count))
        For Each c As Constraint In table.Constraints
            If TypeOf c Is UniqueConstraint Then
                Dim uc As UniqueConstraint = DirectCast(c, UniqueConstraint)
                DumpUniqueConstraintToHtml(uc, dump)
            ElseIf TypeOf c Is ForeignKeyConstraint Then
                Dim fkc As ForeignKeyConstraint = DirectCast(c, ForeignKeyConstraint)
                DumpForeignKeyConstraintToHtml(fkc, dump)
            End If
        Next
        Return dump.ToString()
    End Function
    <System.Runtime.CompilerServices.Extension()> _
    Public Function DumpRelationsToHtml(ByVal dataSet As DataSet) As String
        Dim dump As New StringBuilder
        dump.Append(String.Format("<style>{0}</style>", GetHtmlStyle()))
        dump.Append(String.Format("<p>DataSetName {0}</p>", dataSet.DataSetName))
        dump.Append(String.Format("<p>Relations {0}</p>", dataSet.Relations.Count))
        For Each dr As DataRelation In dataSet.Relations
            dump.Append(String.Format("<p><b>RelationName {0}</b></p>", dr.RelationName))
            dump.Append(String.Format("<p>ParentTable {0}</p>", dr.ParentTable.TableName))
            dump.Append(String.Format("<p>ChildTable {0}</p>", dr.ChildTable.TableName))
            dump.Append(String.Format("<p>Nested {0}</p>", dr.Nested))
            dump.Append("<p>ParentColumns</p>")
            dump.Append("<ul>")
            For Each col As DataColumn In dr.ParentColumns
                dump.Append(String.Format("<li>{0}</li>", col.ColumnName))
            Next
            dump.Append("</ul>")
            If Not dr.ParentKeyConstraint Is Nothing Then
                dump.Append(String.Format("<p><b>ParentKeyConstraint</b></li>", dr.ParentKeyConstraint.ConstraintName))
                DumpUniqueConstraintToHtml(dr.ParentKeyConstraint, dump)
            End If
            dump.Append("<p>ChildColumns</p>")
            dump.Append("<ul>")
            For Each col As DataColumn In dr.ChildColumns
                dump.Append(String.Format("<li>{0}</li>", col.ColumnName))
            Next
            dump.Append("</ul>")
            If Not dr.ChildKeyConstraint Is Nothing Then
                dump.Append(String.Format("<p><b>ChildKeyConstraint</b></li>", dr.ChildKeyConstraint.ConstraintName))
                DumpForeignKeyConstraintToHtml(dr.ChildKeyConstraint, dump)
            End If
        Next
        Return dump.ToString()
    End Function
End Module

Teniendo disponible el código en nuestro proyecto podríamos agregar a la ventana inspección algo como esto:



  • MiDataTable.DumpConstraintsToHtml()

  • MiDataSet.DumpRelationsToHtml()

Y con el visualizador de HTML veríamos lo siguiente (fíjate que incluso en el código de los métodos extensores hemos agregado la etiqueta style de HTML para poder ajustar un poco el resultado):


image


image


No quiero acabar este post sin revelarte el amigo que sin él saberlo me impulsó a escribir este post. Estoy hablando de Óscar Osotorrio… y por supuesto no dejes de visitar su blog que te será muy útil seguro http://oscarsotorrio.com/ 


Un saludo!

No hay comentarios:

Publicar un comentario