具有相同 Id 键字段的多对多
Many-to-many with Same Id Key fields
如何在 nHibernate 中以多对一和一对多的方式连接两个表。它们都具有与键列相同的 'PLAN_ID'。我的数据库结构预先存在。
下面是我正在使用的映射和我遇到的错误:
Table: PLANN (一个)
PLAN_ID <-- PRIMARY KEY
START_DATE
CHECK_CHAR
...
Table:PLANN_DOCUMENT(很多)
PLAN_ID <-- PRIMARY KEY
DOC_ID <-- ID to a DOCUMENT table
DOC_NAME
DOC_TYPE
计划class:
public virtual... PlanId, StartDate, CheckChar, PlanStatus,
public virtual ISet<DocsysHoldingDoc> DocsysHoldingDocs { get; set; }
public virtual DocsysHoldingDoc DocsysHoldingDoc { get; set; }
计划文档Class:
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>
ERROR:
NHibernate.MappingException: 'Unable to build the insert statement for class <>.PlannDocument: a failure occurred when adding the Id of the class'
ArgumentException: The column 'PLAN_ID' has already been added in this SQL builder Parameter name: columnName
我是不是做错了什么?
根据您的评论(在已删除的答案下),table 中主键列的名称相同 - 即 PLAN_ID
。您想根据多对一关系连接这两个 table。
这里的问题是相同的列名(来自两个不同的 table)在映射中被添加了两次。
这就是错误的原因:
ERROR: NHibernate.MappingException: 'Unable to build the insert statement for class <>.PlannDocument: a failure occured when adding the Id of the class'
ArgumentException: The column 'PLAN_ID' has already been added in this SQL builder Parameter name: columnName
在 PlannDocument HBM 中,创建 id
时首先使用列名 PLAN_ID
,如下所示:
<id name="PlanId" column="PLAN_ID" type = "int">
然后,在创建 many-to-one
关系时再次如下:
<many-to-one name="Plann" column="PLAN_ID"></many-to-one>
这导致了列名冲突。
我能想到的解决方案是将列名更改为与其他 table 不同的名称。此外,相应地修改 类 和映射。
我知道这不可能是所有情况下的解决方案。
如果您对 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
可以为 null 而不是使用 constrained="false"
。但请注意,这将花费您额外的查询来检查 Plann
是否真的存在。
如何在 nHibernate 中以多对一和一对多的方式连接两个表。它们都具有与键列相同的 'PLAN_ID'。我的数据库结构预先存在。
下面是我正在使用的映射和我遇到的错误:
Table: PLANN (一个)
PLAN_ID <-- PRIMARY KEY
START_DATE
CHECK_CHAR
...
Table:PLANN_DOCUMENT(很多)
PLAN_ID <-- PRIMARY KEY
DOC_ID <-- ID to a DOCUMENT table
DOC_NAME
DOC_TYPE
计划class:
public virtual... PlanId, StartDate, CheckChar, PlanStatus,
public virtual ISet<DocsysHoldingDoc> DocsysHoldingDocs { get; set; }
public virtual DocsysHoldingDoc DocsysHoldingDoc { get; set; }
计划文档Class:
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>
ERROR: NHibernate.MappingException: 'Unable to build the insert statement for class <>.PlannDocument: a failure occurred when adding the Id of the class'
ArgumentException: The column 'PLAN_ID' has already been added in this SQL builder Parameter name: columnName
我是不是做错了什么?
根据您的评论(在已删除的答案下),table 中主键列的名称相同 - 即 PLAN_ID
。您想根据多对一关系连接这两个 table。
这里的问题是相同的列名(来自两个不同的 table)在映射中被添加了两次。
这就是错误的原因:
ERROR: NHibernate.MappingException: 'Unable to build the insert statement for class <>.PlannDocument: a failure occured when adding the Id of the class'
ArgumentException: The column 'PLAN_ID' has already been added in this SQL builder Parameter name: columnName
在 PlannDocument HBM 中,创建 id
时首先使用列名 PLAN_ID
,如下所示:
<id name="PlanId" column="PLAN_ID" type = "int">
然后,在创建 many-to-one
关系时再次如下:
<many-to-one name="Plann" column="PLAN_ID"></many-to-one>
这导致了列名冲突。
我能想到的解决方案是将列名更改为与其他 table 不同的名称。此外,相应地修改 类 和映射。
我知道这不可能是所有情况下的解决方案。
如果您对 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
可以为 null 而不是使用 constrained="false"
。但请注意,这将花费您额外的查询来检查 Plann
是否真的存在。