私が働いている会社はERPを使用しており、そのレガシーデータベースはOracleです。今まではパッケージ (オラクルのストアド プロシージャ) を使用してデータにアクセスしていましたが、年々数が増え続け、今では管理できなくなりました。
私は Nhibernate でいくつかの実験をしようとしていて、いくつかのテーブルのマッピングを開始しました。
すべてのテーブルに複合主キーがあります。簡単な説明:
テーブルオーダー (テーブル名: OCSAORH )
OCHORDN ( PK ) => 注文
番号 OCHAMND ( PK )
OCHCOSC ( PK ) => 会社
OCHCLII
...
テーブル OrderLine (テーブル名: OCSALIN )
OCLORDN ( PK ) => 注文
番号 OCLAMND ( PK )
OCLCOSC ( PK ) => 会社
OCLLINN ( PK ) => 明細番号
OCLSSEQ ( PK )
OCLITMN
...
これが私のマッピングです
注文:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MvcOracleNhibernate"
namespace="MvcOracleNhibernate.Domain">
<class name="Order" table="OCSAORH">
<composite-id>
<key-property name="Number" column="OCHORDN"></key-property>
<key-property name="Ver" column="OCHAMND"></key-property>
<key-property name="Company" column="OCHCOSC"></key-property>
</composite-id>
<property name="CustomerCode" column="OCHCLII" type="String" length="10"></property>
<property name="Reference" column="OCHOCNO" type="String" length="25"></property>
<property name="Date" column="OCHOCDT" type="Double"></property>
<bag name="OrderLines" cascade="all-delete-orphan" generic="true" inverse="true" lazy="false">
<key>
<column name="OCLORDN" not-null="true"/>
<column name="OCLAMND" not-null="true"/>
<column name="OCLCOSC" not-null="true"/>
</key>
<one-to-many class="OrderLine" not-found="ignore"/>
</bag>
</class>
</hibernate-mapping>
オーダーライン:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MvcOracleNhibernate"
namespace="MvcOracleNhibernate.Domain">
<class name="OrderLine" table="OCSALIN">
<composite-id>
<key-property name="Number" column="OCLORDN"></key-property>
<key-property name="Ver" column="OCLAMND" ></key-property>
<key-property name="Company" column="OCLCOSC"></key-property>
<key-property name="Line" column="OCLLINN"></key-property>
<key-property name="Seq" column="OCLSSEQ"></key-property>
</composite-id>
<property name="Item" column="OCLITMN" type="String" length="19"></property>
<property name="Quantity" column="OCLQTYP" type="Double"></property>
</class>
</hibernate-mapping>
これらのマッピングを使用すると、すべてが正常に機能します。注文を読み込むことができ、遅延読み込みによって明細が読み込まれます。いくつかのドキュメントを読んでいるときに、多対 1 の関係を定義していないことに気付いたので、これを追加しました。
<many-to-one name="Order" class="Order" lazy="proxy">
<column name="OCHORDN" not-null="true"/>
<column name="OCHAMND" not-null="true"/>
<column name="OCHCOSC" not-null="true"/>
</many-to-one>
OrderLine マッピング ファイルに追加します。
テスト アプリを実行すると、注文は正しく読み込まれますが、注文明細行は読み込まれません。{NHibernate.ADOException} = {"could not initialize a collection: ... }
が
発生しました。調査を試みたところ、行を取得するために生成されたクエリが間違っていることがわかりました。これが SQL です。
SELECT
orderlines0_.OCLORDN as OCLORDN1_,
orderlines0_.OCLAMND as OCLAMND1_,
orderlines0_.OCLCOSC as OCLCOSC1_,
orderlines0_.OCLLINN as OCLLINN1_,
orderlines0_.OCLSSEQ as OCLSSEQ1_,
orderlines0_.OCLORDN as OCLORDN13_0_,
orderlines0_.OCLAMND as OCLAMND13_0_,
orderlines0_.OCLCOSC as OCLCOSC13_0_,
orderlines0_.OCLLINN as OCLLINN13_0_,
orderlines0_.OCLSSEQ as OCLSSEQ13_0_,
orderlines0_.OCLITMN as OCLITMN13_0_,
orderlines0_.OCLQTYP as OCLQTYP13_0_,
orderlines0_.OCHORDN as OCHORDN13_0_,
orderlines0_.OCHAMND as OCHAMND13_0_,
orderlines0_.OCHCOSC as OCHCOSC13_0_
FROM OCSALIN orderlines0_
WHERE
orderlines0_.OCLORDN=?
and orderlines0_.OCLAMND=?
and orderlines0_.OCLCOSC=?
お気づきのように、select の最後の 3 つのフィールド (OCL ではなく OCH というプレフィックスが付いたフィールド) は、OCSALIN テーブルのメンバーではありません。それらは OCSAORH のキーです。
ドキュメントと例を読んで1日過ごした後、何が間違っているのかわかりません。
助けようとする人はいますか?