6

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!

Respuesta

4

La entidad de raíz distintiva solo funciona si carga un elemento principal y elementos secundarios. Para nietos y bisnietos esto no funciona. El problema es que está cargando varias asociaciones de colecciones y devolviendo un gran cartesian product

Lea esto article by Ayende que explica por qué este es el caso y una solución alternativa.

Algo que puede no ser evidente inmediatamente va a dar como resultado un producto cartesiano . Esto se señala en el documentation, pero I creo que todos podemos estar de acuerdo en que, aunque puede haber motivos para este comportamiento , está lejos de ser ideal.

+1

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

+0

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

+0

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

Cuestiones relacionadas