0

我有旧的遗留数据库,它们的表中有死链接。我有像这样在 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

4

2 回答 2

1

遵循 Daniel Schilling 使用 where exists 子查询获取可见实体的想法,发现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>

没有其他东西需要改变。

于 2013-08-22T12:01:06.327 回答
0
<key-many-to-one column="sub_object_id" name="SubObject" not-found="ignore" />

...可能会有所帮助。从NHibernate 文档...

ignore将缺失的行视为空关联

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

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

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

我刚刚遇到了这个:与 not-found="ignore" 的关系。我保证我不会复制 Ricci 的内容——我是根据自己的经验写的。

于 2013-08-21T21:25:07.880 回答