我们有一个无法更改的旧数据库。而且我们正在尝试迁移到NHibernate而不是旧的DataAccess层,这是一个垃圾,太慢了。
它具有如下表:
GPI表具有(PU_ID,PAR_ID,Data,Data2)列
BLOCK表具有(GA_ID,Data,PAR_ID)列
COMPANY表具有(PU_ID,数据)列
我已经为上面的表创建了这些映射:
GPI
<class name="GroupPartnerInterest" table="[GPI]">
<composite-id >
<key-property name="GroupId" column="PAR_ID" />
<key-property name="CompanyId" column="PU_ID" />
</composite-id>
<property name="data" column="Data"/>
<property name="data2" column="Data2"/>
<many-to-one name="Company" fetch="select" cascade="none">
<column name="PU_ID"/>
</many-to-one>
<set name="Blocks" cascade="none" inverse="true" fetch="select">
<key property-ref="GroupId">
<column name="PAR_ID"/>
</key>
<one-to-many class="Block"/>
</set>
</class>
堵塞
<class name="Block" table="[BLOCK]" >
<id name="BlockId" column="GA_ID" >
<generator class="assigned"/>
</id>
<property name="data" column="Data"/>
<property name="GroupId" column="PAR_ID"/>
<set name="GroupPartnerInterests" cascade="all-delete-orphan" fetch="select">
<key property-ref="GroupId">
<column name="PAR_ID"/>
</key>
<one-to-many class="GroupPartnerInterest"/>
</set>
</class>
公司
<class name="Company" table="[COMPANY]">
<id name="CompanyId" column="PU_ID">
<generator class="assigned"/>
</id>
<property name="data" column="Data"/>
<set name="GroupPartnerInterests" cascade="none" inverse="true" fetch="select">
<key>
<column name="PU_ID"/>
</key>
<one-to-many class="GroupPartnerInterest"/>
</set>
</class>
这些类非常简单明了。全部实现Equals和GetHashCode方法。
以下是适用的导航器列表:
而这两个失败:
我有一个单元测试:
[TestMethod]
public void TestGroupPartnerInterests()
{
using ( ISession session = SessionFactory.OpenSession() )
{
IList<Block> blocks = session.CreateCriteria( typeof( Block ) )
.SetMaxResults( 5 ).List<Block>();
foreach ( var block in blocks )
{
TestContext.WriteLine( "Block #{0}", block.BlockId );
if ( block.GroupPartnerInterests != null )
{
foreach ( GroupPartnerInterest gpi in block.GroupPartnerInterests )
{
TestContext.WriteLine( "Company '{0}':", gpi.Company.CompanyId );
}
}
}
}
}
如果我注释掉了GPI映射测试中的Blocks导航映射,并且输出了一些数据:
但是测试失败,并显示以下错误:
“999”是现有的PAR_ID-数据是一致的:此PAR_ID有两个块,GPI中有一些记录。
为什么有时会关闭 session ?
单元测试与我上面提到的几乎相同,只是使用了不同的属性。
错误如下:
如果从GPI映射中的“块”导航器的元素中删除“property-ref = GroupId”,我将得到以下异常:
有什么方法可以将Block映射到GPI,以便GroupPartnerInterest.Blocks导航器可以工作?
谢谢,
亚历克斯
最佳答案
问题如下:
id,所有对它的引用都必须
维护复合ID,因此
必须是两个外键。
GroupPartnerInterest
中的块是一个集合,因此外键位于Blocks
中,指向GroupPartnerInterest
。这将需要两个外键,这些外键不可用。 property-ref
将主键替换为其他属性。因此,它是表在关系的一侧的属性,即GroupPartnerInterest
,但没有GroupId
。 property-ref
用作GroupPartnerInterest.Blocks
(因为缺少两个外键,以使Block.PAR_ID
指向GPI.PAR_ID
),但是我会三思而后行。 我无法在这里为您提供有效的解决方案。我不使用复合键,这更复杂。但是还有更多的想法:
为什么 session 关闭?我不知道,我将看一下堆栈跟踪。真的是在using块内抛出了异常吗?还是从
TestCleanup
方法抛出?关于NHibernate导航器映射到组合键问题的一部分-旧版数据库用法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3537021/