NHibernate schafft Proxy über session.Load (), aber nicht über Linq oder Criteria API
-
10-07-2019 - |
Frage
Ich habe ein seltsames Problem in meinem aktuellen Projekt. Verzögertes Laden für Abfragen nicht funktioniert. Wenn ich eine Liste abfragen, holt nhibernate alle Assoziationen getrennt.
I extrahiert kleine Teile davon und es in eine separate Lösung gebracht. Im Grunde, was ich jetzt habe, ist eine Konto-Tabelle und eine AccountSync-Tabelle. Beide haben eine ID und eine URL, während die ID ist nur ein db-guid.
Meine Klassen sind:
public class HippoAccount
{
public virtual Guid Id { get; set; }
public virtual string Url { get; set; }
public virtual HippoAccountSync Sync { get; set; }
}
public class HippoAccountSync
{
public virtual Guid Id { get; set; }
public virtual string Url { get; set; }
public virtual HippoAccount Account { get; set; }
}
Wenn ich lade jetzt ein Objekt über es guid:
var account = session.Load<HippoAccount>(accountId);
Console.WriteLine(NHibernateUtil.IsPropertyInitialized(account, "Sync"))
... es gibt false
und Konto selbst ist ein Proxy-Server.
Aber wenn eine Liste über die Kriterien API geladen:
var account = (HippoAccount)session
.CreateCriteria(typeof (HippoAccount))
.Add(Restrictions.Eq("Id", accountId))
.List()[0];
... die Eigenschaft Sync
wird initialisiert (eine zweite Auswahlabfrage Brennen), und das zurückgegebene Objekt ist kein Proxy-Server.
Ist das Standardverhalten? Was bekomme ich falsch?
Die Abbildung ist:
<class name="HippoAccount" table="AllAccounts">
<id name="Id" type="guid">
<generator class="guid"/>
</id>
<property name="Url" />
<many-to-one
class="HippoAccountSync"
name="Sync"
not-found="ignore"
property-ref="Url">
<column name="url" />
</many-to-one>
</class>
<class name="HippoAccountSync"
mutable="false"
table="Accounts">
<id name="Id" type="guid">
<generator class="guid"/>
</id>
<property name="Url">
<column name="serviceUri" />
</property>
<many-to-one class="HippoAccount"
name="Account"
property-ref="Url"
not-found="ignore">
<column name="serviceUri" />
</many-to-one>
</class>
Lösung
Nach einiger mehr Forschung, fand ich die Antworten. Antworten, denn es gibt viele Dinge, die träges Laden in NHibernate verhindern kann.
-
Abfrage vs. session.Load: Wenn ein Element über
session.Load()
Holen erhalten Sie einen Proxy-Server. Aber sobald Sie Zugriff auf jede Eigenschaft, läßt dieUrl
sagen, das Objekt geholt einschließlich all seinen Assoziationen, die nicht faul Laden nicht unterstützt. -
Immobilien-ref: Lazy Loading funktioniert nur über ein Objekt-ID. Wenn ein Objekt-Verband über eine andere Spalte in der Zieleinheit gelöst ist, holt NH es eifrig. Nicht, dass dies nicht möglich sein würde, ist es einfach nicht umgesetzt: Bug
-
not-found = "ignorieren" kann ungültig Fremdschlüssel, das heißt, wenn die referenzierte Entität nicht NH die Eigenschaft wird init mit null gefunden wird . NH abfangen nicht die Eigenschaft-Zugang für verzögertes Laden, sondern assignes ein Objekt-Proxy. Mit
not-found="ignore"
kann es nicht entscheiden, ob die Eigenschaft sollte für den gegebenen, möglicherweise ungültig, Fremdschlüssel auf null oder einen Proxy eingestellt werden. Dies möglicherweise durch das Abfangen der Eigenschaft Zugriff gelöst werden könnte. -
Wenn
not-found="ignore"
deaktivieren und das Schemaproperty-ref
Exportbeschränkungen erzeugen würde, die eine kreisförmige Referenz erzwingen. Nicht gut! Die richtige Zuordnung wäre dann eine eingeschränkten Eins-zu-Eins-Beziehung, wo der Schlüssel fürHippoAccountSync
einen Generatorforeign
hat.
Ressourcen