lunes, 6 de abril de 2009

Nhibernate: Composite Key

Después de meses creando una clase separada para definir la llave compuesta, nos percatamos que esto no es necesario, y la podemos crear en la misma clase. Para que no nos vuelva a ocurrir posteo el ejemplo:

Tabla:
TABLA_COMPUESTA

LLAVE1 (NUMBER)
LLAVE2 (NUMBER)
DESC (VARCHAR2)
OBS (VARCHAR2)

Mapping:
TablaCompuesta.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true">
<class name="ProjectEntities.TablaCompuesta, ProjectEntities" table="TABLA_COMPUESTA">
<composite-id>
<key-property name="llave1" column="llave1" type="Int32"/>
<key-property name="llave2" column="llave2" type="Int32"/>
</composite-id>
<property name="desc" column="desc" type="String"/>
<property name="obs" column="obs" type="String"/>
</class>

Clase:
TablaCompuesta.vb

Public Class TablaCompuesta

Private _llave1 Int32
Private _llave2 As Int32
Private _desc As String
Private _obs As String

Public Overridable Property llave1() As Int32
Get
Return Me._llave1
End Get
Set(ByVal value As Int32
Me._llave1 = value
End Set
End Property

Public Overridable Property llave2() As Int32
Get
Return Me._llave2
End Get
Set(ByVal value As Int32)
Me._llave2 = value
End Set
End Property

Public Overridable Property desc() As String
Get
Return Me._desc
End Get
Set(ByVal value As String)
Me._desc = value
End Set
End Property

Public Overridable Property obs() As String
Get
Return Me._obs
End Get
Set(ByVal value As String)
Me._obs = value
End Set
End Property

Public Overrides Function Equals(ByVal obj As Object) As Boolean
Return MyBase.Equals(obj)
End Function

Public Overrides Function GetHashCode() As Integer
Return MyBase.GetHashCode
End Function
End Class

martes, 31 de marzo de 2009

Oracle: Unpivot artesanal

Todos estamos esperando utilizar el Oracle 11 que nos ahorre estos dolores de cabeza, pero mientras llega...

Si alguna vez se han preguntado ¿Puedo cambiar mis columnas a filas? Ejemplo:

Tenemos:
UNIDAD VALOR1 VALOR2 VALOR3
1 100 200 300
2 400 500 600

Queremos:
UNIDAD VALOR PRECIO
1 VALOR1 100
1 VALOR2 200
1 VALOR3 300
2 VALOR1 400
2 VALOR2 500
2 VALOR3 600

Sí! Es posible! Esto se llama unpivot, y la forma de hacerlo 'a la antigua' es:

SELECT UNIDAD, 'VALOR'l as VALOR,
DECODE(l, 1, VALOR1,
DECODE(l, 2, VALOR2,
DECODE(l, 3, VALOR3,
DECODE(l, 4, VALOR4,
DECODE(l, 5, VALOR5,
DECODE(l, 6, VALOR6 )))))) UNPIVOT
FROM TABLA,
(SELECT level l FROM DUAL X CONNECT BY LEVEL <= 6) NIVEL;

Esta es la página donde aparece el ejemplo:

http://www.club-oracle.com/forums/f6/unpivoting-column-to-row-conversion-techniques-sql-t145/

Mantener el Focus después de Evento TextChanged

Esto parecía una tontería y me demoré como 1,5 horas en encontrar una solución.

Asumamos que tenemos dos campos TextBox. El primero tiene el evento TextChanged y AutoPostBack TRUE, esto es así en mi caso porque luego de que introduzco un número de cuenta se supone que me debe aparecer el nombre de la cuenta. Cuando eso pasaba el focus se perdía para siempre.

Pero el señor del cual adjunto la página encontró la solución. Es demasiado larga para colocarla aquí, así que les comparto el link:

http://gmamaladze.googlepages.com/maintainfocusbetweenpostbacksalsoinasp.n

Nhibernate: Utilizar IN en un NamedQuery

Para poder usar IN se puede hacer utilizando SetParameterList y una lista con los valores a buscar.

Este es el ejemplo:

Nhibernate:
select id_tipo, tipo_dia, descripcion
from tipo_dia
where id_tipo in (:prueba)

VB:
Dim instance As New List(Of Int32)()
instance.Add(1)
instance.Add(2)

q = Me.GetCurrentSession.GetNamedQuery("ConsultaPrueba")
q.SetParameterList("prueba", instance)
Datos = q.List(Of Entities.Datos)()

Es decir, que tal vez desde el WebApps puedas enviar la lista, que opinas :)

Sumar una columna en un Dataset

Buenas compañeros,

El día de ayer me preguntaba si podía hacer una suma de una columna del dataset, pero sin recorrerlo.

Bueno, al parecer, desde la versión 2.0 esto se puede hacer con las funciones compute.

Les envío mi ejemplo y los sitios donde encontré la información:

Suma débitos:
Dim db As Object = dt.Compute("Sum(Monto)", "Mov = 'D'")

Suma créditos:
Dim db As Object = dt.Compute("Sum(Monto)", "Mov = 'C'")

Puntos a considerar:
El primer argumento de la función es el cálculo, y el segundo el filtro.
Permite: SUM, AVG, MIN, MAX, COUNT, y otras más que verán en los links que les adjunto.
Esto NO es permitido: Sum (Monto1 – Monto2). Habría que crear una columna computada y luego sumarla.
Todos los campos de un datatable creado manualmente son string por defecto, o sea que estos cálculos no se pueden hacer. Hay que crear la columna del tipo correcto.
IMPORTANTE: Este método aparentemente no es muy eficiente en datasets demasiado grandes, pero es mejor que recorrer el dataset. En tema de performance lo ideal es hacer esto directamente en la Base de Datos si es posible (http://weblogs.asp.net/eporter/archive/2003/11/11/36977.aspx)

Fuentes:
http://msdn.microsoft.com/es-es/library/system.data.datatable.compute(VS.80).aspx
http://msdn.microsoft.com/es-es/library/system.data.datacolumn.expression(VS.80).aspx