Frage

Ich habe eine Tabelle Elternteil und einen Tisch Kind. Kind enthält einen Fremdschlüssel zu der übergeordneten Tabelle, die eine Beziehung eines Eins-zu-viele-zu schaffen. Hier ist ein Teil meiner Abbildung, die ich mit fließend NHibernate definieren:

public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        WithTable("Parents");

        Id(x => x.Id, "ParentID")
        .WithUnsavedValue(0)
        .GeneratedBy.Identity();

        Map(x => x.Description, "Description");

        HasMany<Child>(x => x.Childs)
        .LazyLoad()
        .WithKeyColumn("ParentID")
        .IsInverse()
        .AsSet();
    }
}

public class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        WithTable("Childs");

        Id(x => x.Id, "ChildID")
        .WithUnsavedValue(0)
        .GeneratedBy.Identity();

        References(x => x.Parent, "ParentID")
            .CanNotBeNull()
            .LazyLoad();
    }
}

Wie man sehen kann ich gesetzt haben LazyLoad auf die Beziehung. dass in meinem Modellklasse Hinweis auch alle Eigenschaften werden als virtuelle gesetzt.

Jetzt für die einfache Abfrage:

ICriteria crit = Session.CreateCriteria(typeof(Child))
    .Add(Expression.Eq("Id", 18));
IList<Child> list = crit.List<Child>();

Und die SQL generiert:

SELECT this_.ChildID            as ChildID5_1_,
       this_.ParentID           as ParentID5_1_,
       parent2_.ParentID    as ParentID4_0_,
       parent2_.Description as Descript2_4_0_
FROM   Childs this_
       inner join Parents parent2_
         on this_.ParentID = parent2_.ParentID
WHERE  this_.ChildID = 18 /* @p0 */

Wie Sie sehen können, ist es ein an den Eltern-Join-Tabelle und wählt seine Felder (id und Beschreibung). Aber warum ist es, dass tun, da ich Lazy Loading angefordert?

Wenn ich nun die Abfrage zu ändern:

ICriteria crit2 = Session.CreateCriteria(typeof(Child))
    .SetFetchMode("Parent", FetchMode.Lazy)
    .Add(Expression.Eq("Id", 18));

Es gibt zwei SQL-Abfragen generiert:

SELECT this_.ChildID  as ChildID5_0_,
       this_.ParentID as ParentID5_0_
FROM   Childs this_
WHERE  this_.ChildID = 18 /* @p0 */

was für mich gut ist: nein beitreten möchte, wird die übergeordnete Tabelle nicht abgefragt. Aber ich habe diese zweite auch:

SELECT parent0_.ParentID    as ParentID4_0_,
       parent0_.Description as Descript2_4_0_
FROM   Parents parent0_
WHERE  parent0_.ParentID = 45 /* @p0 */

, die wieder die übergeordnete Tabelle abfragt.

Diese 2-Abfragen werden in der Leitung erzeugt:

IList<Child> list = crit.List<Child>();

Ich bin völlig unwissend von dem, was hier passiert. Kann jemand helfen?

War es hilfreich?

Lösung

Es wird auf Ihrer Version von Fluent NHibernate abhängen. Bis vor einem bestimmten Punkt war es der Standard, dass alle Entitäten würden nicht faul geladen werden. Dies ist das Äquivalent von explizit lazy="false" in Ihrem Unternehmen setzen. Dies ist nicht mehr der Fall, aber wenn man vor diesem Punkt auf etwas läuft dann werden Sie dieses Verhalten sehen.

Die many-to-one / Referenzen faul Lasteinstellung wird von der Unternehmensebene faul Last von dem Ziel außer Kraft gesetzt, wenn Sie also auf dieser älteren Version von FNH ausgeführt wird, dann wird das Unternehmen Einstellung Ihres References(...).LazyLoad() Anruf strittig zu machen.

Sie müssen überprüfen Sie die neueste Version von FNH sind, die Dinge beheben sollten; aber wenn es dann nicht müssen Sie explizit verzögertes Laden setzen in Ihrer Parent Einheit. Sie können das tun mit der LazyLoad Methode auf dem ClassMap<T>.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top