0

我正在使用的一家公司正在使用ERP,它的传统数据库是Oracle。 到目前为止,我已经使用包(Oracle存储过程)来访问数据,但在这些年中,数量一直在增长,现在我无法管理它们了。
我试图用Nhibernate做一些实验,并开始映射几张表。
所有表都有复合主键。 简短描述:在Nhibernate中映射具有外键关系的复合主键

表顺序(表名:OCSAORH

OCHORDN(PK)=> ORDERNUMBER
OCHAMND(PK
OCHCOSC(PK)=>公司
OCHCLII
...

表订单行(表名:OCSALIN

OCLORDN(PK)=> ORDERNUMBER
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> 

通过这些映射一切正常;我可以加载订单,而延迟加载加载我的行。 在阅读一些文件我已经注意到,所以我加入这个我还没有定义很多一对一的关系:

<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} = {“无法初始化集合:...} 我试着调查并注意到生成的查询来检索行是错误的。这是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=? 

正如你可以看到选择的最后3场(带有前缀OCH代替OCL)不是OCSALIN表的成员,他们是OCSAORH的关键。
经过1天的阅读文档和例子,我无法弄清楚我做错了什么。
有没有人可以尝试帮忙?

回答

2

这是预期的行为。您正在定义多对一映射中的外键。所以这些列需要存在于你定义的对象中。

我想你想这

<many-to-one name="Order" class="Order" lazy="proxy"> 
    <column name="OCLORDN" not-null="true"/> 
    <column name="OCLAMND" not-null="true"/> 
    <column name="OCLCOSC" not-null="true"/> 
</many-to-one> 
+0

它的工作原理就像一个魅力。感谢Yads。你有没有链接到我可以阅读更多关于这些东西的文档?再次感谢。 – LeftyX 2010-12-22 09:13:48