Archivo por días: 1 octubre, 2022

Generar las clases (de VB o C#) de una tabla de SQL Server o Access (mdb)

Pues eso… este post es para tener actualizada la utilidad CrearClaseTabla que en su día (allá por 2004) creé para generar o crear clases para acceder a una base de datos de SQL Server o de Access.

La idea de esta utilidad (la aplicación y la DLL que es la que hace el trabajo) es crear clases de Visual Basic o C# de cada tabla de la base de datos, con idea de facilitar el acceso por código a esas tablas.

 

Actualizado el código y publicada una release en GitHub

Pues eso, con fecha de hoy 14 de mayo de 2023 he estado puliendo un poco el código tanto de la DLL que se encarga de hacer la conversión como del EXE que hace de intermediario.

En GitHub está todo, tanto el código fuente de VB y C# para la aplicación de Windows con un paquete con el exe para Windows.
Y también el código para .NET MAUI para aplicaciones móviles, ya sabes Windows, iOs y Android.

También he agregado las clases ConversorTipos.vb y ConversorTipos.cs que utiliza el código generado para hacer las conversiones de tipos.

 

En la última actualización de hoy 1 de octubre de 2022 se contempla, entre otras cosas, la definición de variables asignadas sin indicar el tipo (inferencia de tipos) además de convertir adecuadamente las conversiones de tipo de Visual Basic a C# (aunque en el código solo uso CInt).

Nota:
He creado el proyecto para .NET 6.0 (Windows) y está disponible en GitHub: gsCrearClasesTablas.
Por ahora el código es el mismo en este nuevo proyecto como en el que referencio en este post/artículo que es para .NET Framework 4.8.1

El código «base» que utilizo es el que yo uso con Visual Basic y la clase CrearClase apoyada de ConvLag se encarga de generar el código de Visual Basic o el de C#.

Por ejemplo, el código que te muestro primero, en el generador de clases lo defino como te muestro en el segundo bloque de código:

Este es el código en que me he basado:

        cmd.Transaction = tran
        cmd.ExecuteNonQuery()

        ' Si llega aquí es que todo fue bien,
        ' por tanto, llamamos al método Commit.
        tran.Commit()

        msg = "Se ha actualizado el Cliente correctamente."

    Catch ex As Exception
        msg = $"ERROR: {ex.Message}"
        ' Si hay error, deshacemos lo que se haya hecho.
        Try
            If tran IsNot Nothing Then
                tran.Rollback()
            End If
        Catch ex2 As Exception
            msg = $" (ERROR RollBack: {ex.Message})"
        End Try

    Finally
        con.Close()
    End Try

End Using

Return msg

Este es el código interno que uso en el conversor (el método generarClase):
En los comentarios está el código mostrado antes y el equivalente para generar el código de VB o de C#.

sb.AppendLine()
'         cmd.Transaction = tran
sb.AppendFormat("            {0}{1}", ConvLang.Asigna("cmd.Transaction", "tran"), vbCrLf)
'         cmd.ExecuteNonQuery()
sb.AppendFormat("            {0}{1}", ConvLang.Instruccion("cmd.ExecuteNonQuery()"), vbCrLf)
sb.AppendLine()
'         ' Si llega aquí es que todo fue bien,
'         ' por tanto, llamamos al método Commit
sb.AppendFormat("            {0}{1}", ConvLang.Comentario(" Si llega aquí es que todo fue bien,"), vbCrLf)
sb.AppendFormat("            {0}{1}", ConvLang.Comentario(" por tanto, llamamos al método Commit."), vbCrLf)
'         tran.Commit()
sb.AppendFormat("            {0}{1}", ConvLang.Instruccion("tran.Commit()"), vbCrLf)
sb.AppendLine()
'         msg = "Se ha actualizado el Cliente correctamente."
sb.AppendFormat("            {0}{1}", ConvLang.Asigna("msg", """Se ha actualizado un " & nombreClase & " correctamente."""), vbCrLf)
sb.AppendLine()
'     Catch ex As Exception
sb.AppendFormat("            {0}{1}", ConvLang.Catch("ex", "Exception"), vbCrLf)
'         msg = $"ERROR: {ex.Message}"
sb.AppendFormat("              {0}{1}", ConvLang.Asigna("msg", "$""ERROR: {ex.Message}"""), vbCrLf)
'         ' Si hay error, deshacemos lo que se haya hecho
sb.AppendFormat("              {0}{1}", ConvLang.Comentario(" Si hay error, deshacemos lo que se haya hecho."), vbCrLf)
'         Try
sb.AppendFormat("              {0}{1}", ConvLang.Try(), vbCrLf)
' Añadir comprobación de nulo en el objeto tran     (17-abr-21)
'   If tran IsNot Nothing Then
sb.AppendFormat("                  {0}{1}", ConvLang.If("tran", "IsNot", "Nothing"), vbCrLf)
'             tran.Rollback()
sb.AppendFormat("                        {0}{1}", ConvLang.Instruccion("tran.Rollback()"), vbCrLf)
' End If
sb.AppendFormat("                  {0}{1}", ConvLang.EndIf, vbCrLf)
'         Catch ex2 As Exception
sb.AppendFormat("              {0}{1}", ConvLang.Catch("ex2", "Exception"), vbCrLf)
'             msg &= $" (ERROR RollBack: {ex.Message})"
sb.AppendFormat("               {0}{1}", ConvLang.Asigna("msg", "$""ERROR RollBack: {ex2.Message}"""), vbCrLf)
'         End Try
sb.AppendFormat("              {0}{1}", ConvLang.EndTry(), vbCrLf)
sb.AppendLine()
sb.AppendFormat("            {0}{1}", ConvLang.Finally, vbCrLf)
' If Not (con is nothing) then
sb.AppendFormat("              {0}{1}", ConvLang.If("", "Not", "(con Is Nothing)"), vbCrLf)
'     con.Close()
sb.AppendFormat("                  {0}{1}", ConvLang.Instruccion("con.Close()"), vbCrLf)
' End If
sb.AppendFormat("              {0}{1}", ConvLang.EndIf, vbCrLf)
'     End Try
sb.AppendFormat("            {0}{1}", ConvLang.EndTry(), vbCrLf)
sb.AppendLine()
' End Using
sb.AppendFormat("            {0}{1}", ConvLang.EndUsing(), vbCrLf)
sb.AppendLine()
' Return msg
sb.AppendFormat("            {0}{1}", ConvLang.Return("msg"), vbCrLf)

Y el código generado de Visual Basic sería como te he mostrado arriba y el de C# sería más o menos este:

cmd.Transaction = tran;
cmd.ExecuteNonQuery();

// Si llega aquí es que todo fue bien,
// por tanto, llamamos al método Commit.
tran.Commit();

msg = "Se ha actualizado un Producto correctamente.";

}catch(Exception ex){
  msg = $"ERROR: {ex.Message}";
  // Si hay error, deshacemos lo que se haya hecho.
  try{
      if(tran  !=   null ){
            tran.Rollback();
      }
  }catch(Exception ex2){
   msg = $"ERROR RollBack: {ex2.Message}";
  }

finally{
  if(  !  (con  ==   null )){
      con.Close();
  }
}

}

return msg;

Como ves, no está bien formateado, (es el código generado directamente) pero si lo pegas en Visual Studio te lo formateará bien y lo coloreará mejor 😉

Y para muestra, ese trozo de código en un fichero abierto en Visual Studio 2022:
(Aunque todo hay que decirlo, en VB lo formatea bien, aunque solo sea un fichero abierto directamente (sin formar parte de ningún proyecto) mientras que en C# le he tenido casi que dar el formato manualmente, en fin…)

    cmd.Transaction = tran;
    cmd.ExecuteNonQuery();

    // Si llega aquí es que todo fue bien,
    // por tanto, llamamos al método Commit.
    tran.Commit();

    msg = "Se ha actualizado un Producto correctamente.";

}
catch(Exception ex)
{
      msg = $"ERROR: {ex.Message}";
      // Si hay error, deshacemos lo que se haya hecho.
    try
    {
        if (tran != null) 
        {
            tran.Rollback();
        }
    }
    catch(Exception ex2)
    {
        msg = $"ERROR RollBack: {ex2.Message}";
    }

    finally
    {
        if (!(con == null))
        {
          con.Close();
        }
    }
}

Pero la idea es que te quedes con lo que la clase hace.

También es cierto que yo suelo generar el código para Visual Basic y es lo que realmente he probado más, hoy he estado viendo cómo lo generaría para C# y he estado haciendo algunas correcciones (que he indicado en el fichero Revisiones.md publicado con GitHub).

Lo publicado originalmente en elGuilel.info

Los enlaces originales en www.elguille.info son estos:
– La página principal de la utilidad: Generar clases para acceder a una tabla.
– La página con el código y esas cosas: Utilidad para generar clases para acceder a una tabla.
– La página de actualización de cómo conseguir el código fuente: Esta me da error y estaba en CodePlex, ahora está en GitHub.

El final (del post)

Una captura de la utilidad tal como la tengo a día 1 de octubre de 2022.

Figura 1. La utilidad en funcionamiento a día de hoy 1 de octubre de 2022

Y esto es todo amigo (o amiga), ya sabes, si quieres participar en el proyecto para mejorarlo, puedes hacerlo, creo que en algún sitio indico cómo avisarme de los errores que encuentres y cómo actualizar el fichero Revisiones.txt que ahora es Revisiones.md.

Y si quieres usarlo sin más aportaciones, estaría bien que hicieras una pequeña aportación monetaria en PayPal (no es obligatorio, pero es de agradecer).

En breve publicaré en GitHub el ejecutable compilado con .NET Framework 4.8.1.

Nota:
Ya está publicado: gsCrearClaseTabla_20221001_1523.

Y ya sabes, si quieres ver el código fuente, está en el proyecto de GitHub (CrearClaseTabla).

Por cierto, en el proyecto (los dos) he incluido un fichero de nombre seguro (strong name) para firmar los ensamblados, ese fichero (elGuille_compartido.snk) lo puedes usar «libremente» (ya sabes todo está con la licencia MIT) para firmar los ensamblados con nombre seguro.

Espero que te sirva de utilidad.

Nos vemos.
Guillermo

P.S.
Sería interesante convertir el proyecto para .NET 6 (o 7) y también usando el código completamente en C#.
Actualmente está creado para usar con .NET Framework 4.8.1 y escrito enteramente en Visual Basic.

P.S.2
Ya está creado el proyecto para .NET 6.0 (net6.0-windows) y publicado en GitHub (gsCrearClasesTablas).