如何在nHibernate中将两个表多对一和一对多地联接在一起。它们都有与键列相同的“ PLAN_ID”。 我的数据库结构已经存在。
以下是我正在使用的映射以及出现的错误:
表格: PLANN (-一个-)
PLAN_ID <-- PRIMARY KEY
START_DATE
CHECK_CHAR
...
表: PLANN_DOCUMNET (-很多-)
PLAN_ID <-- PRIMARY KEY
DOC_ID <-- ID to a DOCUMENT table
DOC_NAME
DOC_TYPE
计划班:
public virtual... PlanId, StartDate, CheckChar, PlanStatus,
public virtual ISet<DocsysHoldingDoc> DocsysHoldingDocs { get; set; }
public virtual DocsysHoldingDoc DocsysHoldingDoc { get; set; }
PlannDocument类:
public virtual...PlanId, DocId, DocName, DocType
public virtual Plann PlannItem { get; set; }
平面HBM XML
<class name="Plann" abstract="true" table="PLANN">
<id name="PlanId" column="PLAN_ID"
<generator class="assigned"/>
</id>
<property name="StartDate" column="START_DATE" />
<property name="CHECK_CHAR" column="CHECK_CHAR" />
...
<set name="PlannDocument" table="PLANN_DOCUMNET">
<key column="PLAN_ID"></key> //<<KEY IN JOINING TABLE BUT ALSO ID IN THIS TABLE
<one-to-many class="DocsysHoldingDoc"/>
</set>
</class>
PlannDocument HBM XML
<class name="PlannDocument" abstract="true" table="PLANN_DOCUMNET">
<id name="PlanId" column="PLAN_ID" type = "int">
<generator class="assigned"/>
</id>
<property name="DocId" column="DOC_ID" />
<property name="DocName" column="DOC_NAME" />
<property name="DocType" column="DOC_TYPE" />
<many-to-one name="Plann" column="PLAN_ID"></many-to-one>
</class>
错误: NHibernate.MappingException:'无法为类<>。PlannDocument构建插入语句:添加类的ID时发生故障'
ArgumentException:已在此SQL构建器中添加了列“ PLAN_ID” 参数名称:columnName
我在这里做傻事吗?
答案 0 :(得分:1)
根据您的评论(在已删除的答案下方),两个表中的主键列的名称相同-即PLAN_ID
。您想基于多对一关系将这两个表连接起来。
这里的问题是在映射中两次添加了相同的列名(来自两个不同的表)。
这就是为什么出现错误:
错误:NHibernate.MappingException:'无法为类<>建立插入语句。 PlannDocument :添加类的ID时发生故障'
ArgumentException:已在此SQL构建器中添加列'PLAN_ID'。参数名称:columnName
在PlannDocument HBM中,如下创建列PLAN_ID
时首先使用列名id
:
<id name="PlanId" column="PLAN_ID" type = "int">
,然后再次如下创建many-to-one
关系:
<many-to-one name="Plann" column="PLAN_ID"></many-to-one>
这导致列名冲突。
我能想到的解决方案是将列名更改为其他表中的其他名称。另外,相应地修改类和映射。
我了解这并非每次都能在所有条件下解决。
答案 1 :(得分:1)
如果您为identifier
和所需的many-to-one
关联使用相同的列-这实际上不是many-to-one
关联。共享相同的identifier
表示one-to-one
关联。只需使用它而不是您在PlannDocument.hbm.xml中的many-to-one
映射,它应该可以工作:
<one-to-one name="Plann" constrained="true" />
如果您的PlannDocument.Plann
可以为空,则使用constrained="false"
代替。但是请注意,这将使您花费更多的查询来检查Plann
是否确实存在。