nhibernate composite-id,不存在key-many-to-one记录

时间:2013-08-20 21:29:56

标签: nhibernate composite-id

我有旧的旧数据库,它们的表中有死链接。我有像这样在nhibernate中映射的类:

<class name="Visible" table="table_visible">
    <composite-id>
        <key-many-to-one column="object_id" name="ObjectA" />
        <key-many-to-one column="sub_object_id" name="SubObject" />
    </composite-id>
    <property column="visible" name="VisibleRow" />
</class>

public class Visible
{
    public virtual ObjectAClass ObjectA { get; set; }
    public virtual SubObjectClass SubObject { get; set; }
    public virtual bool VisibleRow { get; set; }

    public override bool Equals(object obj)
    {
        var other = ((Visible)obj);
        return this.ObjectA.Equals(other.ObjectA) && this.SubObject.Equals(other.SubObject);
    }

    public override int GetHashCode()
    {
        return this.ObjectA.GetHashCode() + (this.SubObject != null? this.SubObject.GetHashCode(): 0);
    }
}

现在一切正常,当数据库中的所有连接都正确时,但是当我发现这样的sub_object_id没有实体时,nhibernate会抛出错误

No row with the given identifier exists:[SubObject#123]

有没有办法映射复合键,这样当找不到它的子实体时,整个实体就不会被加载(比如内连接)?

NHibernate v2.0.50727

2 个答案:

答案 0 :(得分:1)

遵循Daniel Schilling关于使用where where子查询获取可见实体的想法,发现映射中有loader个元素。

<class name="ObjectA" table="table_object">
    .........   
    <set name="VisibleList" cascade="all" lazy="false" inverse="true">
        <key column="object_id" />
        <one-to-many class="Visible" />
        <loader query-ref="valid_entities"/>
    </set>

</class>
<sql-query name="valid_entities">
    <load-collection alias="v" role="ObjectA.VisibleList"/>
    SELECT {v.*}
    FROM table_visible v
    INNER JOIN table_sub_entities e ON e.sub_entity_id=v.sub_entity_id
    WHERE v.object_id=?
</sql-query>

没有其他事情需要改变。

答案 1 :(得分:0)

<key-many-to-one column="sub_object_id" name="SubObject" not-found="ignore" />

......可能会有所帮助。来自NHibernate Documentation ...

  

ignore会将缺失的行视为空关联

请注意与使用此选项相关的性能损失。每当NHibernate获取Visible实体时,它也必须获取SubObject。如果你不继续在你的查询中获取它,这意味着NHibernate将发出大量的延迟加载。

这不符合您的“当找不到其子实体时,整个实体将无法加载”目标。相反,NHibernate将为您提供一个具有空子实体的实体。如果您想要类似内部联接的行为,那么我认为您需要使用Visible子查询来获取where exists个实体,以确保SubObject实际存在。

最佳选项是修复数据库中的数据并添加外键约束。

我刚刚遇到过这个问题:Relations with not-found="ignore"。我保证我不会复制利玛窦的内容 - 我是根据自己的经验写的。