本文介绍了NHibernate导航器映射到组合键问题的一部分-旧版数据库用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个无法更改的旧数据库.而且我们正在尝试迁移到NHibernate而不是旧的DataAccess层,这是一个垃圾,太慢了.

We have a legacy database that we cannot change. And we are trying to move to the NHibernate instead of old DataAccess layer which is a garbage and is too slow.

它具有如下表格:

GPI表具有(PU_ID,PAR_ID,Data,Data2)列
BLOCK表具有(GA_ID,Data,PAR_ID)列
COMPANY表具有(PU_ID,数据)列

GPI table has (PU_ID, PAR_ID, Data, Data2) columns
BLOCK table has (GA_ID, Data, PAR_ID) columns
COMPANY table has (PU_ID, Data) columns

我已经为上面的表创建了这些映射:

I had created these mappings for the tables above:

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方法.

The classes are very simple and plain. All implement Equals and GetHashCode methods.

以下是适用的导航器列表:

Here is the list of navigators that work:

  • GroupPartnerInterest.Company-很棒
  • Company.GroupPartnerInterests-效果很好
  • GroupPartnerInterest.Company-很棒

这两个失败了:

  • Block.GroupPartnerInterests:

我有一个单元测试:

[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映射测试中的块"导航映射,并输出了一些数据:

If I comment out Blocks navigation mapping in GPI mapping test works and outputs some data:

但是测试失败,并显示以下错误:

But the test fails with the following error:

"999"是现有的PAR_ID-数据是一致的:此PAR_ID有两个块,GPI中有一些记录.

The '999' is existing PAR_ID - data is consistent: there are two blocks with this PAR_ID and a few records in GPI.

为什么在某个时候关闭会话?

  • GroupPartnerInterest.Blocks:

单元测试与我上面提到的几乎相同,只是使用了不同的属性.错误如下:

The unit test is almost the same as I mentioned above, just different properties are used.An error is below:

如果我从GPI映射中的块"导航器的元素中删除"property-ref = GroupId",我将得到以下异常:

If I remove "property-ref=GroupId" from the element of Blocks navigator in the GPI mapping, I will get the following exception:

是否可以将Block映射到GPI,以便GroupPartnerInterest.Blocks导航器正常工作?

谢谢,亚历克斯

推荐答案

问题如下:

  • 如果您的实体包含复合材料id,所有对它的引用都必须维护复合ID,因此必须是两个外键.
  • GroupPartnerInterest中的块是一个集合,因此外键位于Blocks中,指向GroupPartnerInterest.它将需要两个外键,这些外键不可用.
  • property-ref将用其他一些属性替换主键.因此,它是表在关系的一侧的属性,即GroupPartnerInterest,但没有GroupId.
  • 可以可能将property-ref用于GroupPartnerInterest.Blocks(因为缺少两个外键,以使Block.PAR_ID指向GPI.PAR_ID),但是我会三思而后行.
  • If you have a entity with a compositeid, all references to it mustmaintain the composite id, so theremust be two foreign keys.
  • Blocks in GroupPartnerInterest is a set, so the foreign key is in Blocks, pointing to GroupPartnerInterest. It would require two foreign keys, which are not available.
  • property-ref is to replace the primary key with some other property. It is therefore a property of the table on the one-side of the relation, which is GroupPartnerInterest, but there is no GroupId.
  • You could probably use property-ref for GroupPartnerInterest.Blocks (because the two foreign keys are missing, to make Block.PAR_ID point to GPI.PAR_ID), but I would think twice about it.

在这里我无法给您提供有效的解决方案.我不使用复合键,这更复杂.但是还有更多的想法:

I can't give you a working solution here. I don't use composite keys and this is more complex. But there are some more thoughts:

  • 我会尽量避免使用组合键.如果不可能,请编写一个代表组合键的类.这样可以更轻松地处理它.
  • 我会尽量避免不基于主键的关系.可能有其他原因,NH支持他们,我只是认为它们会引起麻烦.

为什么会议关闭?我不知道,我将看一下堆栈跟踪.真的是在using块内抛出了异常吗?还是从TestCleanup方法抛出的?

Why is the session closed? I don't know, I would take a look at the stack trace. It the exception really thrown from within the using block? Or is it thrown from a TestCleanup method?

这篇关于NHibernate导航器映射到组合键问题的一部分-旧版数据库用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 03:37