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.
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).