NHibernateは - ストアドプロシージャと複合キー
-
11-09-2019 - |
質問
私はNHibernateはを使用して私のプロジェクト内のオブジェクトに、ストアドプロシージャの出力をマップしようとしています。
オブジェクトは、次のようにdelcaredされます:
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();
}
}
とのマッピングは、次のようになります:
<?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>
ストアドプロシージャの呼び出しが正しいか、と私は(一例として)SalesRoleId 266については、このように見える結果を取り戻すます:
CMIId FeatureDesc FeatureId Name Count
4000719 Guest Book 12 Charlie Brown 2
4000719 Audio Guest Book 3 Charlie Brown 1
CMIIdを共有する(上記のように)2件の結果がある場合を除き(単にCMIIdを使用して)複合キーが、うまく動作しないと... 2が最初に上書きされる。
私は複合キーを使用する必要があり、かつCMIId / FEATUREIDは、論理的な組み合わせです。
私は今、これを実行すると、私は例外を取得します:
NHibernate.ADOException: could not execute query
[ exec core.spWebGetNewContentBySalesRole ? ]
Name: SalesRoleId - Value: 266
[SQL: exec core.spWebGetNewContentBySalesRole ?] ---> System.IndexOutOfRangeException: CMIId22_0_.
解決
[OK]を、さらなる研究では、ストアドプロシージャを使用する場合、それはNHibernateは、複合IDを持ってすることはできませんことを私に確信しています。
そのために、私は(ROWNUMBERを含めるように私のSQLを修正された)、私はIDとしてこれを使用しています。それは読み取り専用ですので、私は唯一のDBへの書き込みなしで、これを行うことができますが、それは私の目的のために働きます。
他のヒント
は、過去に私はいつも複合用に別のキーに一致するクラスのプロパティとそのIDのために別のクラスを作成するために持っていた複合キーを使用しましたとき。あなたはこれを試したことがありますか?
受け入れ答えで述べたように、私は、ROWNUMの機能を使用して、Oracleでの一意の行番号のハックを使用して終了しました。異なるパラメータでクエリを再利用する場合その後、私が問題に遭遇しました。 NHibernateはこうして間違った行を戻す、IDSを思い出し、新しく返された結果とそれらを関連付けるたかったようです。私はこのようなタイムスタンプを持つ行番号を組み合わせることにより、これを固定
(ROWNUM * 10000000000 + dbms_utility.get_time) AS ROW_ID
この方法では、あなたはあなたのクエリ結果のための全く新しいIDSを毎回取得することが保証しています。ちょうどあなたがあなたのマップされたオブジェクトの値を保持するのに十分な大きさの整数を使用していることを確認してください。私は8バイトであるC#.NETでulong
を使用しています。また、IDを短くするために乗算器のうちのいくつかの0を取ることができます。
日中少し遅れますが、私はできた2番目のMark Struzinski - 。これが可能である。
私は最近、この問題に遭遇した複合キーの別のクラスを使用して、以下のようにマッピング内の要素を使用して、それを解決します。
<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>
「名前」が戻り列の要素が結果セットに名前を表す内部属性、およびIDクラスのプロパティと同じ順序でなければならないことに注意してください。