6

Zuerst, ja, ich benutze DistinctRootEntityResultTransformer.Duplikate, wenn eifrig eine Referenz abgerufen wird (viele-zu-eins)

Ich habe folgende (fliessend NHibernate) Mapping:

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

Hinweis, dass second zu ThirdObject bezieht (die Taste Bedeutung ist auf second).

Meine Abfrage sieht wie folgt aus:

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

Für die Prüfung, ich habe 1 Firstobject, 1 second, 1 ThirdObject und 24 FourthObjects in der Datenbank. Die SQL-Abfrage gibt 24 Zeilen wie erwartet zurück.

aber hier ist der Haken: NHibernate erstellt:

1 FirstObject 
    24 SecondObject (should be 1) 
    24 x 1 ThirdObject (should be 1) 
     24 x 1 x 24 FourthObject (should be 24) 

So NH aus irgendeinem Grund schafft 24 second statt 1.

Ich vermute, es nicht weiß, wie „zur Karte beitreten fetch "(links oder innerlich scheint nicht wichtig zu sein) zu Reference (der Verweis auf ThirdObject in SecondObject).

Was sind meine Optionen? Ich kann das Datenmodell nicht ändern, aber ich muss es unbedingt laden.

Vielen Dank im Voraus!

Antwort

4

Distinct root entity funktioniert nur, wenn Sie einen Eltern und Kinder laden. Für Enkel und Urenkel funktioniert das nicht. Das Problem ist, laden Sie mehrere Sammlung Verbände und eine große cartesian product

Bitte lesen Sie diese article by Ayende, die erklärt, warum dies der Fall ist und eine Problemumgehung.

Etwas, das nicht sofort offensichtlich sein wird, wird zu einem kartesischen Produkt führen. Dies wird in der documentation hingewiesen, aber ich denke, dass wir alle zustimmen können, dass, obwohl es Gründe für dieses Verhalten geben kann, es weit von ideal ist.

+1

Soweit ich weiß, tritt das kartesische Produkt nur auf, wenn parallele Verbindungen hinzugefügt werden. Zum Beispiel, wenn A B1 und B2 hat, dann würde das zu einem kartesischen Produkt führen. Ayende zeigt in seinem Blog genau diese Situation (aus Blog b links beitreten holen b.Posten links beitreten fetch b.Users). Aber wenn A, B, C, D hierarchisch sind (wie ich), sollten sie kein kartesisches Produkt erstellen. Das Problem, mit dem ich konfrontiert bin, ist, dass ich eine Eins-zu-Eins, eine Eins-zu-Eins, eine Viele-zu-Eins-Hierarchie, eine Viele-zu-Eins-Hierarchie habe. Richtig? – user315648

+0

Nein, ich glaube nicht, dass das richtig ist, Sie laden viele -> eins -> viele -> eins. Schauen Sie sich das generierte SQL an und führen Sie es gegen die Datenbank aus, um zu sehen, was passiert. – Rippo

+0

Es ist die 3. bis 4. Beziehung, die die Mehrfachsammlungsverknüpfungen verursacht und somit 24 zweite Objekte erzeugt. – Rippo

Verwandte Themen