NHibernate Filtersammlung
-
07-07-2019 - |
Frage
Mit NHibernate Ich mag eine Sammlung in einer Klasse filtern, dass nur eine Teilmenge der möglichen Objekte zu enthalten. Im Folgenden werde ich eine Beispieltabelle Daten bin auch zu helfen, zu erklären. Ich kann keinen Weg finden, dies mit NHibernate zu tun.
Tabelle: Datenobjekt
DataObjectId (PK) / Name / Currentversion
11 "data.txt" 2
12 "info.txt" 3
Tabelle: DataObjectVersion
Id / Kommentar / Version / DataObjectId (FK)
31 "Genesis" 1 11 <= Ignore this object
32 "Changed data" 2 11 <= Get this object
34 "Genesis" 1 12 <= Ignore this object
35 "Changed info" 2 12 <= Ignore this object
36 "Added info" 3 12 <= Get this object
Ich mag auf einem Nicht-Fremdschlüssel DataObject.CurrentVersion = DataObjectVersion.VersionNumber für jedes Datenobjekt in einem Befehl verbinden.
Hier sind die Klassen und Mapping-Dateien:
public class DataObject
{
public virtual int DataObjectId { get; set; }
public virtual string Name { get; set; }
public virtual int CurrentVersionNumber { get; set; }
public virtual IList<DataObjectVersion> Versions { get; set; }
}
<class name="DataObject" table="DataObject" lazy="false">
<id name="DataObjectId" column="DataObjectId" type="int">
<generator class="assigned" />
</id>
<property name="Name" column="Name" type="String(512)" />
<property name="CurrentVersionNumber" column="CurrentVersionNumber" type="int" />
<bag name="Versions" cascade="all-delete-orphan" inverse="true" lazy="false" >
<key column="DataObjectId" />
<one-to-many class="DataObjectVersion" />
</bag>
</class>
public class DataObjectVersion
{
public virtual int DataObjectVersionId { get; set; }
public virtual string Comment { get; set; }
public virtual int VersionNumber { get; set; }
public virtual int DataObjectId { get; set; }
}
<class name="DataObjectVersion" table="DataObjectVersion" lazy="false">
<id name="Id" column="DataObjectVersionId" type="int">
<generator class="assigned" />
</id>
<property name="Comment" column="Comment" type="String(512)" />
<property name="VersionNumber" column="VersionNumber" type="int" />
<property name="DataObjectId" column="DataObjectId" type="int" />
</class>
Lösung
Wenn Sie die Sammlung auf Nachfrage filtern möchten, unter Verwendung eines Filters ist eine gültige Wahl. Sie müßten die Filter sowohl auf der Version der Klasse und in der Tasche Elemente und wenden die Filter aus der NHibernateSession.EnableFilter Methode
erklären,Wenn Sie wollen immer eine einzige Version in der Tasche holen dann implementieren ein ‚wo‘ in der Abbildung der Tasche:
<bag name="Versions" cascade="all-delete-orphan" inverse="true" lazy="false" where="CurrentVersionNumber = Versions.VersionNumber" >
<key column="DataObjectId" />
<one-to-many class="DataObjectVersion" />
</bag>
beachten Sie, dass in dem ‚wo‘ Sie richtige SQL nicht HQL schreiben und als solche der richtigen SQL oben schreibt es wahrscheinlich geändert werden muss Ihr Schema zu reflektieren
Darüber hinaus, wenn ein einzelnes Objekt ist eine Tasche geholt werden Einrichtung und die nach IList kann ein zu viel des Guten. eine Formel Eigenschaft und ein DataObjectVersion Objekts in der Klasse der Anwendung besser geeignet sein
in der Klasse dataObject- den IList mit
ersetzenpublic virtual DataObjectVersion Version { get; set; }
und bei der Abbildung des ‚Sack‘ mit etwas in den Zeilen
ersetzen<property name="Version" type="DataObjectVersion" update="false" insert="false" formula="(select v.DataObjectVersionId, v.Comments, v.VersionNumber, v.DataObjectId from DataObjectVersion v where v.VersionNumber = CurrentVersionNumber)" />
wieder nur die richtige SQL erlaubt
Ich habe berechnet Eigenschaften mit nativen Datentypen (Datetime, String usw.) und das Abrufen kann ein Unternehmen (oder auch nicht) benötigen verwendet, um etwas mehr oder andere
Last but not least, können Sie einen Filter für die Sammlung anwenden nach Sie haben die primäre Aufgabe Datenobjekt geholt durch einen Filter zu schaffen für die Sammlung
IList<DataObjectVersion> fVersion =
NHibernateSession.CreateFilter(do.Versions, "where VersionNumber = :ver")
.SetParameter("ver", do.CurrentVersionNumber)
.List<DataObjectVersion>();
, wo die Sammlung do.Versions nicht initialisiert ist, werden nur die abgerufenen Ergebnisse in der separaten fVersion Sammlung und dies ist eine zweite SELECT, nachdem bereits den Round-Trip an die DB gemacht zu haben für das Datenobjekt holen.
Andere Tipps
Vermutlich Ihre Version Schritten wie der Benutzer die Daten ändert und Sie versuchen, die neuesten eins zu bekommen. Wenn Sie die Versionsnummer als „Alter“ -Feld statt betrachten (dh, wobei 0 die letzte / jüngste Version ist, 1 ist die nächste älteste und so weiter), dann Ihre Probleme werden wie mit einem Alter von 0. Diese alle Einheiten bekommen Verwendung eines Filters getan werden: http://nhibernate.info/doc/ nh / en / index.html # Object-Filter