Que software debo utilizar para comenzar Nhibernate

6 views
Skip to first unread message

edgitar1984

unread,
Jun 25, 2008, 11:28:36 AM6/25/08
to NHibernate-Hispano
Hola quiero saber como debo empezar para usar nhibernate yo quiero
hacer una aplicacion Web en visual studio 2005 con nhibernate, debo
saber que instalar

Fabio Maulo

unread,
Jun 25, 2008, 11:59:03 AM6/25/08
to NHibernat...@googlegroups.com
Bajate los bin de NH
http://sourceforge.net/project/showfiles.php?group_id=73818

Ya que estas empezando bajate directamente NH2.0.0Alpha2 (el domingo sale la Beta1).

Visita los links de este grupo:
http://groups.google.com.ar/group/NHibernate-Hispano/web/links

Leete y bajate:
http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

Bye.
Fabio Maulo.


2008/6/25 edgitar1984 <edgit...@hotmail.com>:


Hola quiero saber como debo empezar para usar nhibernate yo quiero
hacer una aplicacion Web en visual studio 2005 con nhibernate, debo
saber que instalar





--
Fabio Maulo

Carlos Peix

unread,
Jun 25, 2008, 2:10:38 PM6/25/08
to NHibernat...@googlegroups.com
Nhibernate 1.2.1.4000, .NET 1.1

Tengo el siguiente caso, dos clases:

// Clase Project
public class Project
{
//...
private string code;

private IList tickets = new ArrayList();
public IList Tickets
{
get { return ArrayList.ReadOnly(tickets); }
}

public Ticket AddTicket( string ticketText )
{
Ticket ticket = new Ticket(this, ticketText);
tickets.Add( ticket );
return ticket;
}
}

// y clase ticket
public class Ticket
{
public Ticket(Project project, string text)
{
this.project = project;
this.text = text;
}

//...

private Project project;
public Project Project
{
get { return project; }
}

//...
}

Mapeados asi:

<class name="Project" table="Projects">

<id name="Id" column="Id">
<generator class="guid"/>
</id>

<property name="Code" />
<property name="Description" />
<bag name="Tickets" inverse="true"
cascade="all-delete-orphan" lazy="true">
<key column="IdProject" />
<one-to-many class="Ticket" />
</bag>

</class>
Y
<class name="Ticket" table="Tickets">

<id name="Id" column="Id">
<generator class="guid"/>
</id>

<property name="Text" />
<many-to-one name="Project" column="IdProject"
class="Project" />

</class>

Luego creo tres proyectos en la base de datos:

Project project1 = new Project("1", "Project 1");
project1.AddTicket( "Ticket 1" );
project1.AddTicket( "Ticket 2" );

Project project2 = new Project("2", "Project 2");
project2.AddTicket( "Ticket 1" );
project2.AddTicket( "Ticket 2" );
project2.AddTicket( "Ticket 3" );

Project project3 = new Project("3", "Project 3");

Ahora veamos el problema:

IQuery query = s.CreateQuery( "from Project as p left join fetch
p.Tickets order by p.Code" );
IList list = query.List();
Assert.AreEqual( 3, list.Count );

Este test falla, list.Count es igual a 6!, que es igual a la cantidad filas
que devuelve el join. Dentro del IList tengo dos entradas a la misma
instancia del projecto 1, tres a la del proyecto 2 y 1 del proyecto 3.
Quiero usar el join fetch para que me cargue todos proyectos y tickets en un
solo query.

Por que? Hicimos algo mal?

Si alguno esta interesado, tengo un proyecto con tests que demuestran esto y
generan automaticamente la BD.

Carlos Peix

Carlos Peix

unread,
Jun 25, 2008, 2:10:38 PM6/25/08
to NHibernat...@googlegroups.com
Nhibernate 1.2.1.4000, .NET 1.1

Tengo el siguiente caso (mismo que mail anterior), dos clases:

//...

//...
}

Mapeados asi:

Ahora veamos el problema:


IQuery query = s.CreateQuery(
"select p from Project as p inner join fetch p.Tickets as t
where t.Text like :searchTerm order by p.Code" );
query.SetString("searchTerm", "%1%");
IList list = query.List();
Assert.AreEqual( 2, list.Count );
Assert.AreEqual( 2, ((Project)list[0]).Tickets.Count );

El primer assert pasa, pero el ultimo assert falla,
((Project)list[0]).Tickets.Count es 1, lo cual, para mi es incorrecto. Lo
que yo quiero es una lista con los proyectos cuyos tickets contengan "1" en
el texto. Luego, para cada proyecto, espero que la colección de tickets esta
completa. Quiero usar el join fetch para que me cargue todos proyectos y


tickets en un solo query.

Por que? Hicimos algo mal?

Una cosa que me extraña es que el Manual de NH1.2.1, seccion 11.3.
Associations and joins, anteultimo parrafo

A fetch join does not usually need to assign an alias, because the
associated objects should not be used in the
where clause (or any other clause). Also, the associated objects are not
returned directly in the query results. Instead,
they may be accessed via the parent object.

Nosotros estamos usando un alias del fetch join en el where. Sera este el
error? por que no se puede?

Gustavo Ringel

unread,
Jun 25, 2008, 2:25:47 PM6/25/08
to NHibernat...@googlegroups.com
Hi Carlos, el query que estas haciendo ahi es algo como select P.*, T.* FROM Project P LEFT JOIN Ticket T
 
El cual trae todos los P y los T en una query y tantas filas como matches alla en T y para el caso del projecto sin T trae nulos en T
 
es decir tiene que traer 6...
 
No tengo claro que esperas que devuelva la consulta...a mi gusto tiene que devolver 6 exactamente como esta devolviendo.
 
Gustavo.

Carlos Peix

unread,
Jun 25, 2008, 2:31:44 PM6/25/08
to NHibernat...@googlegroups.com
Gracias Gustavo,
 
Lo que quiero es obtener todos los proyectos con sus tickets pero que use un solo query a la base de datos (por cuestiones de optimizacion).
 
Se me ocurrio que "from Project as p left join fetch p.Tickets order by p.Code" deberia hacer justo eso.
 
Por supuesto, esta prueba que estamos haciendo es una simplificacion de una caso real mucho mas complejo.
 
Gracias por tu tiempo.
 
Carlos Peix


De: NHibernat...@googlegroups.com [mailto:NHibernat...@googlegroups.com] En nombre de Gustavo Ringel
Enviado el: Miércoles, 25 de Junio de 2008 03:26 p.m.
Para: NHibernat...@googlegroups.com
Asunto: [NHibernate-Hispano] Re: Asociaciones y joins (caso 1)

Gustavo Ringel

unread,
Jun 25, 2008, 2:36:22 PM6/25/08
to NHibernat...@googlegroups.com
Carlos, lo que se te ocurrio es correcto si no haces fetch NHibernate podria ir luego y obtener los tickets con selects.

Pero el resultado final del query va a ser 6 o con n+1 selects o segun tu estrategia actual 1 sola. A mi la estrategia me parece correcta, siempre y cuando sea lo que estas buscando.
 
Por supuesto que ya se que lo sabes, pero si siempre quisieras hacer join y no solo para esta consulta lo podes poner en el mapping. Es decir, todo depede de si tenes consultas que usan los ticket y consultas que no.
 
Gustavo. 

Carlos Peix

unread,
Jun 25, 2008, 2:43:39 PM6/25/08
to NHibernat...@googlegroups.com
Gustavo,
 
Perdoname pero no entiendo bien los dos primeros parrafos. El ultimo lo entiendo y es tal como decis, yo quiero hacer el join fetch solo en algunos casos.
 
Volviendo a mi caso, esta bien que me devuelva una lista con 6 proyectos (en realidad referencias repetidas) si tengo tres solamente en la base de datos? No deberia NH darse cuenta de que esta haciendo un join como optimizacion y que no tiene que repetir los proyectos?
 
Carlos Peix
 

De: NHibernat...@googlegroups.com [mailto:NHibernat...@googlegroups.com] En nombre de Gustavo Ringel
Enviado el: Miércoles, 25 de Junio de 2008 03:36 p.m.

Gustavo Ringel

unread,
Jun 25, 2008, 2:57:04 PM6/25/08
to NHibernat...@googlegroups.com
Hi Carlos.
El left join funciona exacto como el left join de la base de datos. Es decir, trae tantos registros como asociaciones alla con la tabla en la derecha del join, y en caso de que no haya ningun registro asociado trae uno solo con nulos en las columnas correspondientes en este caso a tickets.
 
En este caso project 3 no tiene asociacion asi que te trae solo los campos de project 3 y nulo en tickets, project 1 y 2 traen 2 y 3 filas respectivamente con todos los datos de los tickets llenos.
 
from P en este caso lo que hace es devuelver un arreglo de objetos ya que no pusiste nada en el select. en la primer parte del arreglo de objetos tenes P y en la segunda T.
 
Aca tenes un ejemplo de la documentacion de NHibernate para solucionar lo que vos buscas
 
IEnumerable foosAndBars = sess.Enumerable(
    "select foo, bar from Foo foo, Bar bar " +
    "where bar.Date = foo.Date"
);
foreach (object[] tuple in foosAndBars)
{
    Foo foo = tuple[0]; Bar bar = tuple[1];
    ....
}
es decir haces el join y luego obtenes en una recorrida lo que corresponde a p y a t de las tuplas.
 
Abrazo.
 
Tavo.

On Wed, Jun 25, 2008 at 8:43 PM, Carlos Peix <carlo...@gmail.com> wrote:
Gustavo,
 
Perdoname pero no entiendo bien los dos primeros parrafos. El ultimo lo entiendo y es tal como decis, yo quiero hacer el join fetch solo en algunos casos.
 
Volviendo a mi caso, esta bien que me devuelva una lista con 6 proyectos (en realidad referencias repetdas) si tengo tres solamente en la base de datos? No deberia NH darse cuenta de que esta haciendo un join como optimizacion y que no tiene que repetir los proyectos?

Carlos Peix

unread,
Jun 26, 2008, 9:00:52 AM6/26/08
to NHibernat...@googlegroups.com
Gente,
 
A pedido del tano, adjunto el codigo que habia ofrecido. Recuerden que es .NET 1.1 con NH 1.2.1.4000
 
Solo tienen que editar el archivo hibernate.cfg.xml cambiando el server de base de datos y la base de datos. Genera las tablas y las borra.
 
Van a tener, ademas, que rehacer las referencias a NH y Iesi Collections
 
Muchas gracias
 
Carlos Peix
Asociaciones.rar
Reply all
Reply to author
Forward
0 new messages