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>  
War es hilfreich?

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

ersetzen
public 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

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