6

Prima di tutto, si, sto usando DistinctRootEntityResultTransformer.Duplicati quando si desidera recuperare un riferimento (molti-a-uno)

Ho il seguente (perfetto NHibernate) Mappatura:

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"); 
} 

avviso, che si riferisce a secondObject ThirdObject (che significa la chiave è sul secondObject).

La mia domanda si presenta in questo modo:

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>(); 

Per il test, ho 1 FirstObject, 1 secondObject, 1 ThirdObject e 24 FourthObjects nel database. La query SQL restituisce 24 righe come previsto.

Tuttavia, qui sta il trucco: 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) 

Così NH per qualsiasi motivo crea 24 secondObject invece di 1.

Sto indovinando che non sa come mappare "join fetch "(a sinistra o interno non sembra avere importanza) a Reference (il riferimento a ThirdObject in SecondObject).

Quali sono le mie opzioni? Non riesco a cambiare il modello dei dati, ma ho bisogno di caricarli tutti.

Grazie in anticipo!

risposta

4

L'entità radice distinta funziona solo se si carica un genitore e figli. Per nipoti e pronipoti questo non funziona. Il problema è che stai caricando più associazioni di raccolta e restituendo un grande cartesian product

Si prega di leggere questo article by Ayende che spiega perché questo è il caso e una soluzione.

Qualcosa che potrebbe non essere evidente immediatamente sta per risultare in un prodotto cartesiano . Questo è indicato nel documentation, ma I penso che tutti possiamo essere d'accordo sul fatto che mentre ci possono essere ragioni per questo comportamento , è tutt'altro che ideale.

+1

Per quanto ne so, il prodotto cartesiano si verifica solo quando si uniscono associazioni parallele. Ad esempio, se A ha B1 e B2, ciò comporterebbe un prodotto cartesiano. Ayende mostra nel suo blog in modo esatto tale situazione (da Blog b a sinistra unisci fetch b.Post left join fetch b.Users). Ma se A, B, C, D sono gerarchici (come ho), non dovrebbero creare un prodotto cartesiano. Il problema che sto affrontando è che ho una gerarchia molti-a-uno, molti-a-uno, uno-a-molti, molti-a-uno. Giusto? – user315648

+0

No, non credo che sia giusto che tu stia caricando molti -> uno -> molti -> uno. Guarda l'SQL generato ed esegui questo con il database per vedere cosa sta succedendo – Rippo

+0

E 'la terza e quarta relazione che sta causando le associazioni multiple di raccolta creando oggetti 24 secondi – Rippo

Problemi correlati