Primero que nada, sí, estoy usando DistinctRootEntityResultTransformer.Duplica cuando está buscando una referencia (muchos a uno)
I tienen las siguientes (Fluido NHibernate) mapeo:
public FirstObjectMap()
{
Id(x => x.Id):
HasMany<SecondObject>(x => x.SecondItems).KeyColumn("FirstObject_ID");
}
public SecondObjectMap()
{
Id(x => x.Id).Column("ID");
References(x => x.ThirdObject).Column("ThirdObject_ID");
}
public ThirdObjectMap()
{
Id(x => x.Id).Column("ID");
HasMany<D>(x => x.FourthItems).KeyColumn("ThirdObject_ID");
}
public FourthObjectMap()
{
Id(x => x.Id).Column("ID");
}
Aviso, que secondObject refiere a ThirdObject (es decir, la clave está en secondObject).
Mi consulta es la siguiente:
var query = session.CreateQuery("select distinct first from " +
"FirstObject as first " +
"left join fetch first.SecondItems as second " +
"left join fetch second.ThirdObject as third " +
"left join fetch third.FourthItems as four where ...");
// This is not even needed as I'm using distinct in HQL
query.SetResultTransformer(new DistinctRootEntityResultTransformer());
var results = query.List<ReinsurableObject>();
Para las pruebas, tengo 1 firstObject, 1 secondObject, 1 ThirdObject y 24 FourthObjects en la base de datos. La consulta SQL devuelve 24 filas como se esperaba.
Sin embargo, aquí está la trampa: NHibernate crea:
1 FirstObject
24 SecondObject (should be 1)
24 x 1 ThirdObject (should be 1)
24 x 1 x 24 FourthObject (should be 24)
Así NH por cualquier razón crea secondObject 24 en lugar de 1.
supongo que no sabe cómo asignar "se unen fetch "(izquierda o interna no parece importar) a la referencia (la referencia a ThirdObject en SecondObject).
¿Cuáles son mis opciones? No puedo cambiar el modelo de datos, pero sí tengo que cargarlo todo.
¡Gracias de antemano!
Por lo que sé, el producto cartesiano solo se produce cuando se unen asociaciones paralelas. Por ejemplo, si A tiene B1 y B2, eso daría como resultado un producto cartesiano. Ayende muestra en su blog exactamente esa situación (del Blog b izquierda unir buscar b.Posts left join fetch b.Users). Pero si A, B, C, D son jerárquicos (como yo), no deberían crear un producto cartesiano. El problema que estoy enfrentando es que tengo una jerarquía de muchos a uno, muchos a uno, uno a muchos, muchos a uno. ¿Correcto? – user315648
No, no creo que sea correcto, estás cargando muchos -> uno -> muchos -> uno. Mire el SQL generado y ejecútelo en la base de datos para ver lo que está sucediendo – Rippo
Es la 3ª a la 4ª relación que está causando las múltiples asociaciones de recopilación y por lo tanto crea objetos de 24 segundos – Rippo