septiembre 27, 2007

row-locks en operaciones SQL-Insert/Update/Delete

Este es un tip que me paso un cuate llamado Christian que es DBA en SQL Server. Para no poner de rodillas a su servidor de base de datos SQL Server

Un link de referencia adicional es:
http://support.microsoft.com/kb/323630

"A veces por cuestiones de performance o necesidad de trabajar con un conjunto de registros grandes, es conveniente hacerlo parcialmente, es decir, en "pedazos". Esto puede suceder porque al trabajar con millones de registros se generen demasiados row-locks y consuman toda la memoria y el query falle en su ejecución."

Aquí un query de ejemplo:


SET NOCOUNT ON --QUITAMOS LOS MENSAJES DE CONTEO DE REGISTROS AFECTADOS YA QUE LO PERSONALIZAMOS

DECLARE @Afectados bigint --DECLARAMOS UNA VARIABLE PARA ACUMULAR LOS REGISTROS AFECTADOS

DECLARE @Afec bigint --DECLARAMOS UNA VARIABLE PARA SABER CUANTOS ACUMULO EN CADA PASO

SET @Afectados = 0 --INICIALIZAMOS EL ACUMULADO

Borra: --ETIQUETA PARA SALTO

SET Rowcount 1000 --ESTA SENTENCIA ES LA MAS IMPORTANTE: LE DECIMOS AL SQL QUE LA SIGUIENTE SENTENCIA SOLO AFECTARÁ A 1000 REGISTROS (AUNQUE EXISTAN MÁS)!!!!!!.

DELETE Facturas

WHERE Fecha_factura < '2007/01/01' --EJECUTAMOS NUESTRA SENTENCIA, ESTA ES SOLO UN EJEMPLO Y SUPONDREMOS QUE LA SENTENCIA POR SÍ SOLA AFECTARÍA MILLONES DE REGISTROS.

SET @Afec = @@Rowcount --OBTENEMOS CUANTOS REGISTROS AFECTO (SOLAMENTE AL FINAL QUE YA NO HAYA REGISTROS POR AFECTAR DEVOLVERÁ CERO, DE LO CONTRARIO DEVOLVERÁ LOS 1000 QUE CONFIGURAMOS)

SET @Afectados = @Afectados + @Afec

print 'Afectados: ' + CONVERT(varchar,@Afectados) --AQUÍ VAMOS IMPRIMIENDO EL ACUMULADO DE LOS REGISTROS QUE VA AFECTANDO PARA DARNOS UNA IDEA DE CUANTO LEVA. (Ver pantalla resultado al final)

if @Afec > 0 goto borra --SI EL NUMERO DE REGISTROS QUE AFECTO EL DELETE ES MAYOR A CERO (ES DECIR QUE AUN HAY MÁS REGISTROS POR BORRAR) REGRESA A EJECUTAR EL DELETE.

set rowcount 0 --RESETEAMOS EL ROWNCOUNT PARA QUE YA AFECTE NORMAL


El resultado se vería como la siguiente imágen:




Tipos Nulables para valores NULL en Bases de Datos

Hace unos días hice una clase de tipo Entity que la poblabla con registros de una tabla de una Base de Datos y la mayoría de sus valores eran opcionales, es decir nulos así que utilice el concepto de tipos nulables del framework 2.0. Con esta clasecilla insertaba regsitros con valores nulos.

Public Class Cuestionario
'Los miembros privados nulables
Private _otroIdiomaHabla As Nullable(Of Byte)
Private bolv1 As Nullable(Of Boolean)


--los métodos públicos de acceso a los miembros privados.
Public Property OtroIdiomaHabla() As Nullable(Of Byte)
Get
Return Me._otroIdiomaHabla
End Get

Set(ByVal value As Nullable(Of Byte))
Me._otroIdiomaHabla = value
End Set

End Property
End Class


'El uso de la clase
Dim objCuestionario as new Cuestionario
'Asigno nada a su miembro
objCuestionario.OtroIdiomaHabla = Nothing
'Verifico el valor
If objCuestionario.OtroIdiomaHabla.HasValue then
'Existe valor
Else
'Sin valor
End if

'Cuando asigno valor a un comando como parametro a la ejecución de un store procedure 'pasamos el valor o un nothing implicito por el tipo nulable y que equivale a un null en la columna de la tabla de la BD.
cmd.Parameters.Add("@OtroIdiomaHabla", Data.SqlDbType.Bit, 1).Value = objCuestionario.OtroIdiomaHabla

'En el store procedure asignamos un default al parametro y cuando pasamos el valor a través del parametro a nuestro objeto esteremos pasando un nothing que va equivaler al Null.
CREATE PROCEDURE spuInserta
@OtroIdiomaHabla tinyint=NULL
As
Insert Into Tabla (OtroIdiomaHabla, ValorX)
Values(@OtroIdiomaHabla, Default)
Go

Links a páginas de iconos

Como desarrolladores de aplicaciones WEB y de escritorio siempre necesitamos de iconos de todo tipo recientemente consulté dos páginas de iconos simpre utiles para que las agreguen a susu favoritos.

http://www.iconfinder.net/
El siguiente link me lo paso mi cuate Gerardo Hdz.
http://www.iconarchive.com/

Los 7 pecados mortales de Ajax

un buen link teórico de lo bueno y malo de usar Ajax!
http://www.tufuncion.com/errores-ajax

mayo 02, 2007

Serialización con .NET 2.0

Hace unos días tuve la necesidad de serializar un objeto y esto es lo que encontré para el Framework 2.0

Imports System.Xml.Serialization
Imports System.IO

Private Sub SerilizarObj()
Dim serializar As XmlSerializer = New XmlSerializer(GetType(AreaBLL))
'Creamos el objeto a serializar
Dim objArea As New AreaBLL()
objArea.IdArea = 1
objArea.NombreArea = "MKT"
objArea.AreaPadre = "Presidencia"
'Archivo en donde vamos a colocar el objeto deshidratado.
Dim stream1 As New FileStream("C:\area.xml", FileMode.Create)
'Serilizar
serializar.Serialize(stream1, objArea)
stream1.Close()
End Sub

Private Sub DesSerializarObj()
'Obtener a memoria el archivo XML
Dim FileXML As FileStream = New FileStream("C:\area.xml", FileMode.Open)
'Crear un XMLSerializer para manejar la deserialización
Dim serialize As XmlSerializer = New XmlSerializer(GetType(AreaBLL))
'Crear el objeto que se va a rehidratar.
Dim objArea As New AreaBLL
'Deserializar el obj.
objArea = serialize.Deserialize(FileXML)
FileXML.Close()
End Sub

abril 17, 2007

Ejemplo de Aplicación ASP.NET 2.0 en capas con DataSet Tipado

Para el desarrollo de esta aplicación utilizamos Visual Basic .NET con Visual Studio .NET 2005.

Estrucutura del proyecto ASP.NET
- Una carpeta App_Code con:

  • Una clase Area. Que hace uso de los métodos de la Clase del tipo Business Entities representada por un TableAdapter de un DataSet.

  • Una clase DataSet. Contiene un DataSet tipado el cual contiene los TableAdapter que representan a cada uno de los objetos Entitie con sus respectivos métodos de Acceso a Datos.


- La forma Web “Area.aspx” representa a la capa GUI.

Las 3 capas

En una arquitectura en 3 capas tenemos la capa de presentación o GUI, en nuestro ejemplo son los archivos aspx. La capa de Negocio que en nuestro ejemplo la representan nuestras clases Entity ubicados en el DataSet Tipado y para cada objeto entidad existe un TableAdapter con los métodos necesarios para el Acceso a Datos. Y la clase Area que representa como una clase Control que se comunica con las clases Entity y sus metodos de acceso a datos para luego hacer DataBinding con controles en la GUI.

Detalles de la Implementación

Tenemos una tabla llamada Area para la cual queremos implementar una forma de mantenimiento. La pantalla a la que queremos dar funcionalidad con la arquitectura en 3 capas es:



Esta es la estructura de la tabla de la base de datos correspondiente al Area y los datos que regresa el store procedure que estaremos ejecutando.



Implementación del DataSet que contiene a los TableAdapters que representan a nuestros objetos Business Entities.

Algunas de las formas de representar a los Business Entities en la apicación son:
· XML
· DataSet Genericos
· DataSet Tipados
· Componentes Business Entities personaizados
· Componentes Business Entities con comportamiento CRUD

Para nuestro ejemplo utiizaremos el caso de DataSet Tipados. En la siguiente imagen podemos observar como se representa nuestro Business Entiy Area y en la parte baja observamos los métodos de acceso a datos que nos permiten poblar al Businness Entity representado como un DataTable.




Implementación del Objeto Area.

Este objeto es como un objeto control que invoca a los métodos de acceso a datos definidos para cada TableAdapter

Imports Microsoft.VisualBasic

Public Class Area

Public Function ObtenerAreas() As DataSet1.AREADataTable
Dim AreasAdapter As New DataSet1TableAdapters.AREATableAdapter()
Dim Areas As DataSet1.AREADataTable = AreasAdapter.GetData
Return Areas
End Function

End Class

Podemos observar que esta clase crea una instacia del adaptador correspondiente al objeto Entity que deseamos trabajar en este caso: “AreaTableAdapter” luego invocamos su método de acceso a datos llamado GetData que nos regresa un DataTable con cada una de las áreas y que retornamos a la capa GUI para hacer DataBinding con un GridView.

Implementación de la capa de Presentación GUI

En esta capa es en donde vamos a poblar los controles visuales. El GridView se carga durante el evento Load de la página aquí crea una instancia del objeto Control Area y éste expone un método público que obtiene las Area que nos regresa en un objeto DataTable con el cual hacemos DataBinding al GridView.


Partial Class Default2
Inherits System.Web.UI.Page

Dim objArea As New Area

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then

Dim objArea As New Area
Me.GridView1.DataSource = objArea.ObtenerAreas
Me.GridView1.DataBind()

End If
End Sub

'Implementación del Pagineo la Grid
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging
Me.GridView1.PageIndex = e.NewPageIndex
Me.GridView1.DataSource = objArea.ObtenerAreas()
Me.GridView1.DataBind()
End Sub

'Borrar el registro seleccionado en el Grid
Protected Sub GridView1_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles GridView1.RowDeleting
'Para detectar el segundo postback generado por el ButtonField del tipo Image se verifican sus coordenadas x y.
If (Me.Request("x") Is Nothing) AndAlso (Me.Request("y") Is Nothing) Then

Dim iAffect As Int16
objArea = New Area
iAffect = objArea.DeleteArea(Me.GridView1.Rows(e.RowIndex).Cells.Item(0).Text)
Else
Me.GridView1.DataSource = objArea.ObtenerAreas()
Me.GridView1.DataBind()
End If
End Sub

'Al seleccionar un área se muestra en los controles independientes.
Protected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged
Me.LabelIdArea.Text = Me.GridView1.Rows(Me.GridView1.SelectedIndex).Cells.Item(0).Text
Me.TextBox2.Text = Me.GridView1.Rows(Me.GridView1.SelectedIndex).Cells.Item(1).Text
Me.TextBox1.Text = Me.GridView1.Rows(Me.GridView1.SelectedIndex).Cells.Item(2).Text
Me.CheckBox1.Text = Me.GridView1.Rows(Me.GridView1.SelectedIndex).Cells.Item(3).Text
End Sub


End Class

Conclusión: Ésta es una de las formas propuestas por Microsoft.

Ejemplo de una Aplicación ASP.NET 2.0 en 3 capas con Colecciones de Objetos Personalizados

Para el desarrollo de esta aplicación utilizamos Visual Basic .NET con Visual Studio .NET 2005.
La arquitectura es en 3 capas con uso del patrón Mapper.

Estrucutura del proyecto ASP.NET
- Una carpeta App_Code con 3 carpetas.

  • La Carpeta Entities. Esta carpeta contiene a todos las clases que corresponden a los objetos de negocio del tipo entity, es decir objetos persistentes en la Base de Datos

  • La Carpeta ColeccionesObj. Esta carpeta contiene a las clases que operan como colecciones de objetos de los objetos entity, es decir existe un objeto collecion por cada objeto Entity.

  • La Carpeta Mappers. Esta carpeta contiene a las clases encargadas de crear objetos entity uno o más con los registros que obtiene de la base de datos y los objetos creados son consumidos por la capa de presentación. Los objetos mappers contienen los métodos necesarios para obtener y persistir los objetos del tipo Entity. Para cada objeto entity existe un objeto Mapper, pero cada uno de estos tiene el patrón Singleton para asegurar que exista una única instancia en toda la aplicación. Podriamos decir que este objeto es el encargado del acceso a datos y hace uso las objetos entity que devueve a la capa de presentación.









-La forma Web “Area.aspx” representa a la capa GUI

Las 3 capas

En una arquitectura en 3 capas tenemos la capa de presentación o GUI, en nuestro ejemplo son los archivos aspx. La capa de Negocio que en nuestro ejemplo la representan nuestras clases Entity ubicados en la carpeta Entites y la capa de Acceso a Datos representada por los objetos Mappers en nuestra carpeta Mappers y la Capa de datos son los objetos de la Base de Datos en nuestro ejemplo se representa con store procedures. En este caso los objetos Mappers son los encargados de comunicar las 3 capas y pasar datos del mundo relacional al de objetos.


















Detalles de la Implementación

Tenemos una tabla llamada Area para la cual queremos implementar una forma de mantenimiento. La pantalla a la que queremos dar funcionalidad con la arquitectura en 3 capas es:






















Esta es la estructura de a tabla de la base de dato correspondiente al Area y los datos que regresa el store procedure que estaremos ejecutando.























Implementación de la clase Entity (Objeto de Capa de Negocio)

Algunas de las formas de representar a los Business Entities en la aplicación son:
· XML
· DataSet Genericos
· DataSet Tipados
· Componentes Business Entities personaizados
· Componentes Business Entities con comportamiento CRUD



Para nuestro ejemplo utilizaremos el caso de ”Componentes Business Entities Personalizados”.

La clase Entity representa al objeto de negocio Area. Para ello agregamos una Clase en la carpeta Entities con el nombre AreaBLL.

Imports Microsoft.VisualBasic

Public Class AreaBLL

Private _idArea As Integer
Private _nombreArea As String
Private _obsArea As String
Private _esActivaArea As Boolean
Private _fechaModificArea As Date
Private _usrModificArea As String
Private _idAreaPadre As Integer
Private _AreaPadre As String

Public Property IdArea() As Integer
Get
Return Me._idArea
End Get
Set(ByVal value As Integer)
Me._idArea = value
End Set
End Property

Public Property NombreArea() As String
Get
Return Me._nombreArea
End Get
If value.Trim.Length > 0 Then
Me._nombreArea = value
Else
Throw New Exception("Debe proporcionar el nombre del área")
End If
End Property

Public Property ObsArea() As String
Get
Return Me._obsArea
End Get
Set(ByVal value As String)
Me._obsArea = value
End Set
End Property

Public Property EsActivaArea() As Boolean
Get
Return Me._esActivaArea
End Get
Set(ByVal value As Boolean)
Me._esActivaArea = value
End Set
End Property

Public Property FechaModificArea() As Date
Get
Return Me._fechaModificArea
End Get
Set(ByVal value As Date)
Me._fechaModificArea = value
End Set
End Property

Public Property UsrModificArea() As String
Get
Return Me._usrModificArea
End Get
Set(ByVal value As String)
Me._usrModificArea = value
End Set
End Property

Public Property IdAreaPadre() As Integer
Get
Return Me._idAreaPadre
End Get
Set(ByVal value As Integer)
Me._idAreaPadre = value
End Set
End Property

Public Property AreaPadre() As String
Get
Return Me._AreaPadre
End Get
Set(ByVal value As String)
Me._AreaPadre = value
End Set
End Property

End Class

Podemos observar que se compone de propiedades privadas que representan a cada una de las columnas de la tabla. Para que dichas propiedades sean accesibles creamos los métodos públicos que leen o escriben en las propiedades. (Con esto implementamos el concepto de Encapsulamiento de la teoría de la Programación Orientada a Objetos).

Implementación de la clase colección para cada objeto Entity

Ahora requerimos construir una clase que nos permita contener una colección de objetos entidad. Si observamos la pantalla que deseamos dar funcionalidad tenemos una rejilla que debe poblarse con objetos entidad del tipo AreaBLL. Agregamos una clase que llamaremos Area_Coleccion y que debe heredar de la clase CollectionBase.

Imports Microsoft.VisualBasic

Public Class Area_Coleccion
Inherits CollectionBase
Default Public Property Item(ByVal index As Integer) As AreaBLL
Get
Return CType(List(index), AreaBLL)
End Get
Set(ByVal value As AreaBLL)
List(index) = value
End Set
End Property

Public Function Add(ByVal value As AreaBLL) As Integer
Return (List.Add(value))
End Function

Public Function IndexOf(ByVal value As AreaBLL) As Integer
Return (List.IndexOf(value))
End Function

Public Sub Insert(ByVal index As Integer, ByVal value As AreaBLL)
List.Insert(index, value)
End Sub

Public Sub Remove(ByVal value As AreaBLL)
List.Remove(value)
End Sub

Public Function Contains(ByVal value As AreaBLL) As Boolean
Return (List.Contains(value))
End Function
End Class

Podemos observar que los métodos de esta clase reciben objetos del tipo Area. Es así que para cada objeto Entity que tengamos debemos crear un objeto Colección, esto si es que requerimos devolver una colección de objetos a la capa de datos. En nuestro ejemplo si requerimos poblar un GridView que muestra a un conjunto de objetos Area.

Implementación de la clase Mapper para cada objeto Entity

Esta es la clase que se encarga de regresar un objeto Entity a la capa de presentación o una colección de objetos de acuerdo al método invocado.

Como esta clase es la que accede a la base de datos utilizamos el DataBlock de Microsoft. Accedemos a los datos a través de store procedures. La cadena de conexión se encuentra en el archivo web.config


Si observamos el método “GetAllArea” retorna una colección de objetos del tipo Area_Colección. Se extraen los registros de base de datos a través de un SqlDataReader y luego se recorre a cada uno y con cada renglon se pobla un objeto Entity AreaBLL, luego el objeto poblado se agrega a la Colección de objetos Area y así sucesivamente para cada objeto creado de acuerdo a los registros de base de datos obtenidos en el SqlDataReader.

Imports Microsoft.VisualBasic
Imports Microsoft.ApplicationBlocks.Data
Imports System.Data.SqlClient
Imports System.Reflection
Imports System.Data

Public Structure AreaMapper
Private _SQLCon As String

'Propiedades necesarias para implementar la clase como Singleton.
Private Shared mInstance As AreaMapper
Private Shared mMutex As New System.Threading.Mutex()

Public ReadOnly Property SQLCon() As Integer
Get
Return Me._SQLCon
End Get
End Property

'Implementando la clase como Singleton.
Public Shared Function GetInstance() As AreaMapper
mMutex.WaitOne()
If mInstance Is Nothing Then
mInstance = New AreaMapper()
End If
mMutex.ReleaseMutex()
Return mInstance
End Function

Public Sub New()
_SQLCon = ConfigurationManager.ConnectionStrings("TimonConnectionString").ToString()
End Sub

'Iniciar con la cadena de conexión
Sub New(ByVal pSQLCon As String)
_SQLCon = pSQLCon
End Sub

Public Function GetAllArea() As Area_Coleccion
Dim dr As SqlDataReader = Nothing
Try
dr = SqlHelper.ExecuteReader(_SQLCon, Data.CommandType.StoredProcedure, "spSelectArea")
Dim ListaAreas As New Area_Coleccion
While dr.Read()
ListaAreas.Add(PopulateArea(dr))
End While
Return ListaAreas

Catch ex As SqlException
Throw New Exception(ex.Message & " En la rutina: " & MethodInfo.GetCurrentMethod.Name)
Catch ex As Exception
Throw New Exception(ex.Message & " En la rutina: " & MethodInfo.GetCurrentMethod.Name)
Finally
If Not dr Is Nothing AndAlso Not dr.IsClosed Then
dr.Close()
End If
End Try
End Function

Private Function PopulateArea(ByVal dr As SqlDataReader) As AreaBLL
Dim ObjArea As New AreaBLL
Try

ObjArea.IdArea = Convert.ToInt32(dr(0)) 'IdArea
ObjArea.NombreArea = Convert.ToString(dr(1)) 'NombreArea

'ObsArea
If Not dr(2) Is DBNull.Value Then
ObjArea.ObsArea = Convert.ToString(dr(2))
End If

'EsActivaArea
ObjArea.EsActivaArea = Convert.ToByte(dr(3))
'AreaPadre
ObjArea.AreaPadre = Convert.ToString(dr(4))

Return ObjArea

Catch ex As SqlException
Throw New Exception(ex.Message & "En la rutina: " & MethodInfo.GetCurrentMethod.Name)
Catch ex As Exception
Throw New Exception(ex.Message & "En la rutina: " & MethodInfo.GetCurrentMethod.Name)
End Try
End Function


End Structure



Implementación de la capa de Presentación GUI

En esta capa es en donde vamos a poblar los controles visuales con objetos Entity o listas de objetos Entity. Nosotros queremos que la cargarse la forma web se poble el GridView con los datos de todas las áreas que se encuentran en la tabla Area de la base de datos. Hacemos esto en el evento Load. Podemos observar como creamos un objeto de la clase AreaMapper y que para poblar el GridView ejecutamos su método GetAllArea y que lo establecemos como DataSource al GridView a esto se lo conoce como DataBinding con objetos de negocio.

Partial Class _Default
Inherits System.Web.UI.Page

Private ObjAreaMapper As AreaMapper

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
ObjAreaMapper = AreaMapper.GetInstance()
Call poblarDBGrid()
Call poblarListaAreasPadre()

End If
End Sub

Private Sub poblarDBGrid()
Try
Me.GridView1.DataSource = ObjAreaMapper.GetAllArea
Me.GridView1.DataBind()
Me.LabelTotalRegGrid.Text = "Total de Registros: " & Me.GridView1.Rows.Count
Catch ex As Exception
Me.LabelInfo.Text = ex.Message
End Try
End Sub

Private Sub poblarListaAreasPadre()
Try

Me.DropDownList1.DataSource = ObjAreaMapper.SelectAreas
Me.DropDownList1.DataValueField = "IdArea"
Me.DropDownList1.DataTextField = "NombreArea"
Me.DropDownList1.DataBind()

Catch ex As Exception
Me.LabelInfo.Text = ex.Message
End Try
End Sub
End Class


Este es un diagrama que expone de manera general la arquitectura de la aplicación desarrollada






























Referencias
http://msdn2.microsoft.com/en-us/library/ms978496.aspx

http://builder.com.com/5100-6387-1049997.html



Excelente artículo DateSet vs. Colecciones de Objetos

Este es el link a un excelente articulo que expresa ventajas y desventajas de usar DataSets y Colecciones de Objetos, cuando usar unos y otros. Muchas veces como desarrolladores utilizamos lo que nos dicen los manuales de microsoft o los libros, pero no sabemos tecnicamente que es mejor, tomamos lo que mejor entendemos o lo que nos parece más fácil, pero creo que esto no es del todo correcto.

http://msdn.microsoft.com/msdnmag/issues/05/08/CuttingEdge/

Algo de lo que dice este articulo con respecto a los DataSets es que estos implementan la serialización de manera automática, pero ésta tiene un costo muy considerable cuando se hace para miles de registros. Soportan la concurrencia optimista, el databinding , permiten la implementación de links lógicos entre tablas cuyo fin es hacer árboles hijos de datos, pero esto último comunmente no es utilizado.

Con respecto a las colecciones de objetos cuya implementación requiere heredar de la clase
CollectionBase son considerablemente más rápidos en la recuperación de datos entre las capas. Requieren un mayor trabajo de codificación.

En conclusión el artículo propone pensar muy bien en usar DataSet ya que al parecer estos presentan más desventajas , claro esto depende de la funcionalidad que se requiera ya que los DataSet soportan funcionalidad que no soportan las colecciones de objetos aunque estos últimos presentan un mayor desempeño.

marzo 22, 2007

Utiles NET 2.0

Crear y acceder a los métodos de un TableAdapter definido en un DataSet tipado.

'Esta función retorna una DataTable después de crear el TableAdapter y ejecutar el método definido en la mismo.
Public Function ObtenerAreasXEsActiva() As DataSet1.AREADataTable
Dim AreasAdapter As New DataSet1TableAdapters.AREATableAdapter()
Dim Areas As DataSet1.AREADataTable
Areas = AreasAdapter.GetDataByEsActivaArea(1)
Return Areas
End Function

----------------------------------------------------------------

Recuperar de web.config

Forma 1:My.Settings.Item("ConnectionStringCaja")
Forma 2:My.Settings.strSQLServer

-----------------------------------------------------------
Accesar a una celda de un GridView
DataGridView1.Rows(0).Cells(0).Value = DateTime.Now 'Colocar el valor.
DataGridView1.Rows(0).Cells(0).Style.Format = "d"
MessageBox.Show(DataGridView1.Rows(0).Cells(2).Value)

Recuperar el valor de la celda seleccionada en el GridView por ejemplo al evento
SelectedIndexChanged.


sValor = Me.GridView1.Rows(Me.GridView1.SelectedIndex).Cells.Item(0).Text

------------------------------------------------------------

Condición necesaria para manejar el doble postback de un
ButtonField del tipo image en un GridView. Por ejemplo al evento RowDeleting

Protected Sub GridView1_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles GridView1.RowDeleting

If (Me.Request("x") Is Nothing) AndAlso (Me.Request("y") Is Nothing) Then
objArea = New AreaBLL
objArea.DeleteArea(Me.GridView1.Rows(e.RowIndex).Cells.Item(0).Text)
Else
Me.GridView1.DataSource = objArea.ObtenerAreas()
Me.GridView1.DataBind()
End If
End Sub

--------------------------------------------------------------------------------------------

Implementar el pagineo en el GridView


Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging

'Asignar el nuevo índice d página solicitado.
Me.GridView1.PageIndex = e.NewPageIndex
Me.GridView1.DataSource = objArea.ObtenerAreas()
Me.GridView1.DataBind()


End Sub

Utiles SQL Server

Registros que están en A, pero no en B

SELECT NombreEmp FROM EMPLEADO WHERE (IdEmpleado NOT IN (SELECT IdEmpleado FROM EMPLEADO_AREA))

---------------------------------------------------------------------------------------

Obtener registros duplicados

select au_lname count(*) from dup_authors group by au_lname having count(*) > 1

----------------------------------------------------------------------------------------

Consulta con apostrofe

Select ApPat From EmpleadoWhere ApPat = 'O''Rally'

-----------------------------------------------------------------------------------------

Obtener sólo la fecha de un DateTime

SELECT CONVERT(CHAR(10), FechaAltaCustodia, 103) AS SoloFecha FROM FOLIO_CUSTODIA
------------------------------------------------------------------------------------------
Convert con redondeo

Select Convert(numeric(3,0), 987.654)--Salida 988

------------------------------------------------------------------------------------------
Case

SELECT Nombre,
EsActivo= CASE
WHEN EsActivo= 0 THEN 'No'
WHEN EsActivo= 1 THEN 'Si'
END
FROM Tabla1

------------------------------------------------------------------------------------------
Uso de Exist

IF EXISTS(SELECT * FROM authors WHERE au_fname = 'Elmer')
PRINT "Existen los datos"
ELSE

RAISERROR('No existen los datos')

------------------------------------------------------------------------------------------

Utiles VB.NET 1.1

VB NET ASP 1.1
Recuperar el valor de una celda de un DataGrid

En el evento
DataGrid1.SelectedIndexChanged


Session("Id") = Me.DataGrid1.SelectedItem.Cells(0).Text


--------------------------------------------------------------------------------------------
VB NET ASP 1.1
Recuperar el total de renglones en un DataGrid

Session("TotalRenglones") = Me.DataGridMetricasMeta.Items.Count()

--------------------------------------------------------------------------------------------
VB NET ASP 1.1
Obtener el texto del item seleccionado, ya que el dropdownlist no cuenta con una propiedad text directamente.

Me.DropDownListProducto.Items(Me.DropDownListProducto.SelectedIndex).Text

--------------------------------------------------------------------------------------------
VB NET ASP 1.1

Recuperar el valor de archivo web.config

'Extraer la cadena de conexión del archivo web.config en una variable de aplicación.
Application("ServerBD") = ConfigurationSettings.AppSettings("ServerBD")

--------------------------------------------------------------------------------------------
VB NET ASP 1.1
Poner texto en un dropdownlist como si se tratará de una caja de texto.

Me.DropDownList1.SelectedItem.Text = "Seleccione un valor"

--------------------------------------------------------------------------------------------
VB NET ASP 1.1
Ocultar columna del DataGrid

Me.DataGridMetricasMeta.Columns(6).Visible = False

--------------------------------------------------------------------------------------------
VB NET ASP 1.1
Encontrar y seleccionar un item basado en un texto en un DropDownList


DropDownList1.SelectedValue = DropDownList1.Items.FindByText("Ilumina").Value

------------------------------------------------------------------------------------------

Validar existencia de nulo en el resultado de un DataReader

If IsDBNull(dr("ObsDocto")) then

End if

------------------------------------------------------------------------------------------

Pasar parametros a un comando

cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID

cmd.Parameters.Add("@Name", SqlDbType.Int).Value = System.DBNull.Value--Valor nulo

------------------------------------------------------------------------------------------

Ejecutar una Transacción ADO.NET

cn.Open

Dim trans as SqlTrasaction = cn.BeginTransaction
Dim cmDel as New SqlCommand()

cmDel.Connection = cn

cmDel.Transaction = trans


Try

cmDel.CommandText = "Delete TablaDetalle Where Product = 12"

cmDel.ExecuteNonQuery()


cmDel.CommandText = "Delete TablaEnc Where Product = 12"

cmDel.ExecuteNonQuery()


trans.Commit()

Catch Ex as Exception

trans.Rollback()

Finally

cn.Close()

End try

febrero 18, 2007

Tipo Nullable

Por ejemplo el tipo entero (Integer en VB) no tenia forma de tener un valor nulo. Esto permite guardar valores nulos en la base de datos.

'Declarar la variable
Dim nul as Nullable(Of Integer)

'Verificar el valor
If nul.HasValue Then
'Tiene valor
End if

enero 08, 2007

Utilizar el Patron Singleton con formularios MDI

Objetivo: Que desde una aplicación Windows sólo podamos tener una forma hija abierta.

-------1. En la forma hija

'Variable global
Private Shared frmInstance As frmReport = Nothing

'Finalmente crearemos una función shared que será la que finalmente controlara la creación o manejo de la instancia del formulario, logrando obtener solo un formulario 'abierto para este form1.


'Función que verifica sola a una instancia del form1
Public Shared Function Instance() As form1
If frmInstance Is Nothing OrElse frmInstance.IsDisposed = True Then
frmInstance = New form1
End If
frmInstance.BringToFront()
Return frmInstance
End Function

'2-En la forma padre.
'Ahora en el padre escribiremos el llamado al hijo para crear la instancia, o si ya esta 'creada, entonces pondrá el formulario hijo en frente para que lo podamos ver.

Dim frmHijo as form1 = form1.Instance
frmHijo.MdiParent = Me
frmHijo.Show

Referencia:
href="http://www.mentores.net/articulos/Percynet_EditorTexto.htm"

El Patrón Singleton

Objetivo: Hacer que la instancia de un objeto sea accesible globalmente, y que sea única. Para ello es necesario crear un método en la clase que se desee sólo tener una instancia a la ves.

Yo por ejemplo hice un objeto mapper el cuál necesitaba que no fuera instanciado más de una vez por la aplicacion que lo usara.

'---1 La clase Singleton-----------------------------------------------------
Public Class MapperEmpleado
Private pnombre As String

Public Property nombre() As String
Get
Return pnombre
End Get
Set(ByVal Value As String)
pnombre = Value
End Set
End Property

Private Shared mInstance As MapperEmpleado
Private Shared mMutex As New System.Threading.Mutex()

' Constructor privado para no poder instanciar la clase
Private Sub New()
End Sub

'Método que verifica la existencia del objeto al querer instanciar.
Public Shared Function GetInstance() As MapperEmpleado
mMutex.WaitOne()
If mInstance Is Nothing Then
mInstance = New MapperEmpleado()
End If
mMutex.ReleaseMutex()
Return mInstance
End Function

End Class

--2 La aplicación desde que se consume a la clase que implementa el patrón singleton.

'Para poder instanciar el objeto se usa el método GetInstance ya que el constructor New() es privado.
Dim obj As MapperEmpleado = MapperEmpleado.GetInstance
obj.nombre = "Julio"
Dim obj2 As MapperEmpleado = MapperEmpleado.GetInstance
MessageBox.Show(obj2.nombre)
--El nombre es el mismo porque sólo se permite una clase.


Aquí un link de referencia sobre este patrón:
http://www.mug.org.ar/Patrones/ArticPatrones/304.aspx

http://searchvb.techtarget.com/tip/0,289483,sid8_gci921128,00.html