Frage

Ich versuche, die Ausgabe einer gespeicherten Prozedur in meinem Projekt mit NHiNRNATE einem Objekt in meinem Projekt abzubilden.

Das Objekt wird so delcated:

public class NewContentSearchResult
{
    public string Name { get; set; }
    public string ContentType { get; set; }
    public int Count { get; set; }
    public int CMIId { get; set; }
    public int FeatureId { get; set; }

    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

Und die Zuordnung sieht so aus:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Class.Assembly"
    namespace="Class.Assembly"
    default-lazy="false" default-cascade="none">
  <class name="NewContentSearchResult" mutable="false" check="none">
    <composite-id unsaved-value="none">
      <key-property name="CMIId" type="int" />
      <key-property name="FeatureId" type="int" />
    </composite-id>
    <property name="ContentType" type="string" />
    <property name="Name" type="string" />
    <property name="Count" type="int" />
  </class>
  <sql-query name="spWebGetNewContentBySalesRole">
    <return class="NewContentSearchResult" lock-mode="read">
      <return-property name="Name" column="Name" />
      <return-property name="ContentType" column="FeatureDesc" />
      <return-property name="Count" column="Number" />
      <return-property name="CMIId" column="CMIId" />
      <return-property name="FeatureId" column="FeatureId" />
    </return>
    exec core.spWebGetNewContentBySalesRole :SalesRoleId
  </sql-query>
</hibernate-mapping>

Der gespeicherte Proc -Anruf ist korrekt, und ich erhalte zurück -Ergebnisse, die für SalesROLEID 266 (als Beispiel) so aussehen:

CMIId       FeatureDesc       FeatureId     Name       Count
4000719 Guest Book          12     Charlie Brown    2
4000719 Audio Guest Book    3      Charlie Brown    1

Ohne den zusammengesetzten Schlüssel (nur mit dem CMIID) funktioniert es gut, außer wenn es 2 Ergebnisse (wie oben) gibt, die einen CMIID teilen ... der 2. wird von der ersten überschrieben.

Ich muss einen zusammengesetzten Schlüssel verwenden, und CMIID/FeatureID ist die logische Kombination.

Wenn ich das jetzt leite, bekomme ich eine Ausnahme:

NHibernate.ADOException: could not execute query
[ exec core.spWebGetNewContentBySalesRole ? ]
  Name: SalesRoleId - Value: 266
[SQL: exec core.spWebGetNewContentBySalesRole ?] --->  System.IndexOutOfRangeException: CMIId22_0_.
War es hilfreich?

Lösung

OK, weitere Untersuchungen haben mich davon überzeugt, dass es nicht möglich ist, zusammengesetzte IDs in Nhibernate zu haben, wenn Sie ein gespeichertes Verfahren verwenden.

Zu diesem Zweck habe ich meine SQL so geändert, dass Rownumber () einbezieht, und ich benutze das als ID. Ich kann dies nur tun, weil es schreibgeschützt ist, ohne dass es für den DB geschrieben wird, aber es funktioniert für meinen Zweck.

Andere Tipps

In der Vergangenheit, als ich einen Composite-Key verwendet habe, musste ich immer eine separate Klasse für diese ID mit den Eigenschaften der Klasse erstellen, die den separaten Schlüssel für das Composite entspricht. Hast du das versucht?

Wie in der akzeptierten Antwort erwähnt, habe ich mit der Funktion "Rownum" einen eindeutigen Zeilennummer -Hack in Oracle verwendet. Später stieß ich auf ein Problem, als ich die Abfrage mit unterschiedlichen Parametern wiederverwendet habe. Es scheint, dass sich Nhibernate an die IDs erinnert und sie mit neu zurückgegebenen Ergebnissen in Verbindung bringen wollte, wodurch falsche Zeilen zurückgebracht wurden. Ich habe dies behoben, indem ich die Zeilennummer mit einem solchen Zeitstempel kombiniert habe:

(ROWNUM * 10000000000 + dbms_utility.get_time) AS ROW_ID

Auf diese Weise erhalten Sie garantiert jedes Mal völlig neue IDs für Ihre Abfrageergebnisse. Stellen Sie einfach sicher, dass Sie eine große Ganzzahl verwenden, um den Wert in Ihrem zugeordneten Objekt zu halten. Ich benutze ein ulong in C#.NET, das 8 Bytes ist. Sie können auch ein paar 0s aus dem Multiplikator nehmen, um die ID kürzer zu machen.

Ein bisschen spät am Tag, aber ich kann Struzinski zweiten - das ist möglich.

Ich bin kürzlich auf dieses Problem gestoßen und habe es gelöst, indem ich eine separate Klasse für den zusammengesetzten Schlüssel verwendete und Elemente innerhalb der Zuordnung wie folgt verwendet habe.

<sql-query name="spWebGetNewContentBySalesRole" >
    <return class="NewContentSearchResult">
        <return-property name="NewContentSearchResultKey">
            <return-column name="CMIIdColumn" />
            <return-column name="FeatureIdColumn" />
        </return-property>
        <return-property name="Name" column="Name" />       
        <return-property name="ContentType" column="FeatureDesc" />       
        <return-property name="Count" column="Number" />       
    </return>
    exec core.spWebGetNewContentBySalesRole :SalesRoleId 
</sql-query>

Beachten Sie, dass die Attribute "Name" in den Rückkehr-Spalnelementen die Namen im Ergebnissatz darstellen und in derselben Reihenfolge wie die Eigenschaften in der ID-Klasse sein sollten.

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