在NHibernate的复合外键中使用复合主键的一部分 [英] Using part of a composite primary key in a composite foreign key in NHibernate

查看:109
本文介绍了在NHibernate的复合外键中使用复合主键的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个相当大的数据库(约200个表),它几乎全部使用复合主键和复合外键,并使用一个基本表",每个其他表都从该基本表"继承其主键的一部分:

We have a fairly big DB (~200 tables) which almost entirely uses composite primary keys and composite foreign keys, using a single "base table" from which every other table inherits part of its primary key:

  • 父级具有单列主键ParentId
  • 孩子具有复合主键(ParentId,ChildId)和外键ParentId
  • Nephew具有复合主键(ParentId,NephewId),外键ParentId和外键(ParentId,ChildId)

,依此类推.到目前为止,我们已经使用自己的ORM框架管理了整个工作流程,但是我们正在考虑使用NHibernate,我已被分配学习该知识(我已经下载了v2.1.2).

and so on. Up until now we managed this whole shebang with an ORM framework of our own, but we're considering using NHibernate, which I've been assigned to learn (i've downloaded v2.1.2).

映射: 孩子

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Assembly" namespace="Namespace">
<class name="Child" table="Child">
    <composite-id name="IdChild" class="ChildId">
        <key-many-to-one name="Parent" column="ParentId" class="ParentId"></key-many-to-one>
        <key-property name="Id" column="ChildId" type="Int32"></key-property>
    </composite-id>
    <!--simple properties-->
    <set name="Nephews" table="Nephew">
        <key>
            <column name="ParentId"></column>
            <column name="ChildId"></column>
        </key>
        <one-to-many class="Nephew"/>
    </set>
</class>
</hibernate-mapping> 

外星人

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Assembly" namespace="Namespace">
    <class name="Nephew" table="Nephew">
        <composite-id name="IdNephew" class="NephewId">
            <key-many-to-one name="Parent" column="ParentId" class="Parent"></key-many-to-one>
            <key-property name="Id" column="NephewId" type="Int32"></key-property>
        </composite-id>
        <many-to-one name="Child" class="Child">
            <column name="ParentId"></column>
            <column name="ChildId"></column>
        </many-to-one>
        <!--simple properties-->
    </class>

如果您愿意,我也可以发布这些类,为了简洁起见,我现在将其省略(因为我不会省略Parent的映射,因为它没有问题).每个属性都是虚拟的,每个映射文件是一个嵌入式资源,每个复合ID都有自己的类,该类重写Equals和GetHashCode.

I can post the classes too if you want, I'll omit them now for brevity (as I'll omit the mapping for Parent, since it doesn't have problems). Every property is virtual, every mapping file is an embedded resource, every composite Id has its own class which overrides Equals and GetHashCode.

问题是我无法保存Nephew的实例,该实例通过简单的new Nephew()初始化并传递给_session.Save(),因为我得到了System.IndexOutOfRangeException: Invalid index n for this SqlParameterCollection with Count=n..

The problem is I can't save an instance of Nephew, initialized through a simple new Nephew() and passed on to _session.Save(), because I get a System.IndexOutOfRangeException: Invalid index n for this SqlParameterCollection with Count=n..

映射中唯一重复的列是ParentId.删除Nephew中的many-to-one映射,Child中的set映射以及所有相关属性,一切正常.

The only column which is duplicated in the mapping is the ParentId. Removing the many-to-one mapping in the Nephew, the set mapping in the Child and all related properties everything works fine.

我发现了几篇报道此异常的帖子,而在我看来,最合适的帖子是

I found several posts reporting this exception, and the most appropriate in my case seems to be this one, which gives me the gut feeling that my current schema is infeasible with NHibernate. Please tell me I'm wrong :-)

注意:

  • 即使可以选择,我现在也不使用Fluent,但我更喜欢先学习基础知识;
  • 是的,我们意识到复合主键是一个很大的难题.多年来,该数据库已经经过了几手操作,可能不是很熟练,但是在重构之前,我们将达到10,000

推荐答案

我找到了更好的解决方案:

I found a better solution:

<many-to-one name="Child" class="Child">
    <formula>ParentId</formula>
    <column name="ChildId"></column>
</many-to-one>

我已经尝试过了,但是给了我一个错误,但是随后我注意到了此补丁 ,因此我下载了3.0.0 alpha2,并且一切正常!借助此解决方案,我可以按原样映射Nephew.Child属性.

I had already tried that and it gave me an error, but then I noticed this patch, so I downloaded the 3.0.0 alpha2 and it all worked correctly! Thanks to this solution I can map the Nephew.Child property as it was meant to be.

尽管如此,我仍然需要Child.Add(Nephew)方法(但我意识到即使在文档中也建议这样做)

I still need the Child.Add(Nephew) method, though (but I realized that is recommended even in the documentation)

这篇关于在NHibernate的复合外键中使用复合主键的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆