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
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
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?
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];
....
}
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?