Mostrando las entradas con la etiqueta Bernachea. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Bernachea. Mostrar todas las entradas

domingo, 21 de junio de 2009

Como exponer los eventos RowUpdated y RowUpdating en un TableAdapter?

Bueno, después de dar un par de vueltas e investigar un poco, acá les dejo la solución a como exponer los eventos RowUpdated y RowUpdating de un TableAdapter de los generados con diseñador de Dataset fuertemente Tipados.

Tanto en C# 2005 como en C# 2008 tienen que ir al Dataset tipado (xsd).
Identifican al TableAdapter (NO el datatable) que van a modificar y clickean con boton izquierdo.
Van a la ventana de propiedades para el tableadapter y ponen la propidad ConnectionModifier en PUBLIC.

Después clickean con el botón derecho en el mismo TableAdapter y van a la opción Ver Código (View Code) y en la ventana de código agregan la clase parcial necesaria para incorporar el código que expone el dataadapter interno.

El código a continuación es un ejemplo de como debiera queda la clase

namespace WinCon.DataSet1TableAdapters //obviamente acá va el namespace de ustedes
{
using System.Data;
using System.Data.SqlClient; //acá va el provider de la base que ustedes están usando
// en caso que no sea SQL Server

public partial class EjemploTableAdapter //de nuevo, el nombre exacto de su tableadapter
{
public System.Data.SqlClient.SqlDataAdapter Adapter2 //el nombre que se les ocurra
{
get
{
this.Adapter.SelectCommand = this.CommandCollection[0];
return this.Adapter;
}
}
}
}

Hasta acá la modificación, si lo estuvieran invocando por ejemplo desde un windows forms, podrían ejecutar lo siguiente (ojo que ahora el código que viene a continuación está adentro de un windows forms que utiliza al tableadapter).

DataSet1TableAdapters.EjemploTableAdapter da = new WinCon.DataSet1TableAdapters.EjemploTableAdapter();
DataSet1 ds = new DataSet1();


public Form1()
{
//atacho los eventos y digo que lo gestionan
// los métodos metodo y metodo2 respectivamente.
da.Adapter2.RowUpdating += metodo; //fijensé que uso la propiedad Adapter2
// que creé adentro del TableAdapter.
da.Adapter2.RowUpdated += metodo2;
InitializeComponent();
}


Espero que a alguien le sea de utilidad.

Hugo Bernachea
http://www.linkedin.com/in/bernachea

lunes, 5 de enero de 2009

Haciendo Generadores de Codigo con CodeDom

A los que están interesados en realizar sus propios generadores de código en .NET (C# o VB.NET), les dejo un ejemplo para utilizar Codedom (los imports mínimos son: System.CodeDom y System.CodeDom.Compiler )
Lo bueno de CodeDom es que permite generar código de manera genérica pero de implementación concreta, esto es, podemos hacer generadores de código para cualquier de los lenguajes de .NET (c++, C#, Vb.NEt, etc).

Aquí vá el ejemplo que pueden utilizar y probar, este código genera un string con el código de una clase en C# y en VB, con una propiedad llamada ID y un constructor predeterminado. Ideal para comenzar a probar y experimentar.

Dim ns As CodeNamespace 'definiendo un namespace para nuestra clase

Private Sub GeneraClase
'defino un namespace base
ns = New CodeNamespace("PrimerCodeDom")

'agrego los imports correspondientes
'aca pueden agregar todos los imports necesarios
ns.Imports.Add(New CodeNamespaceImport _
("System"))
ns.Imports.Add(New CodeNamespaceImport _
("System.Diagnostics"))
ns.Imports.Add(New CodeNamespaceImport _
("System.Text"))

'creo la clase en si misma
Dim clase As New CodeTypeDeclaration("Clase_Clientes")
'agrego la clase a la colección de tipos
ns.Types.Add(clase)

'defino un campo privado

Dim campo As New CodeMemberField("integer", "_ID")
campo.Attributes = MemberAttributes.Private

'agrego el miembro privado a la clase

clase.Members.Add(campo)

'defino un campo público

Dim p As New CodeMemberProperty()

' le doy un nombre a la propiedad
' ID en este caso
p.Name = "ID"

' lo hago público
p.Attributes = MemberAttributes.Public
p.Type = New CodeTypeReference("System.Int32") 'es integer
p.HasGet = True
p.HasSet = True 'si fuese false, sería solo lectura

'esto que viene es obligatorio
'tengo que decirle que cosa devuelve el get de la propiedad
p.GetStatements.Add( _
New CodeMethodReturnStatement( _
New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "_ID")))
'esto también es obligatorio
'tengo que decirle como se asigna el valor del set
p.SetStatements.Add(New CodeDom.CodeAssignStatement( _
New CodeFieldReferenceExpression( _
New CodeDom.CodeThisReferenceExpression, "_ID"), _
New CodeDom.CodePropertySetValueReferenceExpression))

'agrego la propiedad a la clase
clase.Members.Add(p)

'defino un constructor público

Dim constructor As New CodeConstructor()
constructor.Attributes = MemberAttributes.Public
clase.Members.Add(constructor)

'defino los providers para los lenguajes en los que voy a generar mi clase
Dim csProvider As New Microsoft.CSharp.CSharpCodeProvider
Dim vbprovider As New VBCodeProvider

'en .net 3.5 este código tira un warning por obsoleto,
'pero igual funciona perfecto.
Dim codigo As ICodeGenerator

codigo = vbprovider.CreateGenerator()
Dim vbCod As String = generaCode(codigo)

codigo = csProvider.CreateGenerator
dim csCod as String = generaCode(codigo)

'en este punto, en las variables vbCod y csCod
'tienen el código de la clase correctamente generada.

End Sub

'metodo complementario
Private Function generaCode(ByVal CodeGenerator As ICodeGenerator) As String

Dim options As New CodeGeneratorOptions()

' defino la identación del código
options.IndentString = Space(3)

' creo un StringWriter
Dim sb As New StringBuilder()
Dim sw As StringWriter = New StringWriter(sb)

' genero
CodeGenerator.GenerateCodeFromNamespace(ns, sw, options)

' devuelvo el string con el código generado
Return sb.ToString()
End Function

Una utilidad interesante podría ser utilizar este código para generar un mapeador de clases contra tablas de una base de datos, para lo cual debemos recorrer las tablas de una base de datos, ver código SQL aquí: http://sqldata.blogspot.com/2009/01/como-obtener-todas-las-tablas-de-una.html y por cada tabla recorrer los campos con el Script SQL listado aquí: http://sqldata.blogspot.com/2009/01/como-obtener-todos-los-campos-de-una.html y aplicar el codigo codedom correspondiente para generar un mapeador de clases contra tablas.
O sea, por cada tabla generar la clase en codedom y por cada campo generar dentro de la clase correspondiente las propiedades que necesitemos.

Con eso tienen lo necesario para generarse un mapeador de clases si se ponen manos a la obra.


Hugo Bernachea