NHibernate (3.1) 子类的子查询未加入基类表

发布于 2024-11-07 10:10:47 字数 1785 浏览 5 评论 0原文

以下是我遇到的实际问题的摘要。

public class Base
{
    public virtual string Id { get; set; }
    public virtual string Foo { get; set; }
}

public class Sub : Base
{
    public virtual string Bar { get; set; }
    public virtual Other Other { get; set; }
}

public class Other
{
    public virtual string Id { get; set; }
    public virtual ICollection<Sub> Subs { get; set; }
}

映射:

<class name="Base" table="base_table" xmlns="urn:nhibernate-mapping-2.2">
  <id name="Id" column="id">
    <generator class="assigned" />
  </id>
  <property name="Foo" column="Foo" />

  <joined-subclass name="Sub" table="sub_table">
    <key column="id" />
    <property    name="Bar"   column="Bar" />
    <many-to-one name="Other" column="other_id" />
  </joined-subclass>

</class>

<class name="Other" table="other_table" xmlns="urn:nhibernate-mapping-2.2">
  <id name="Id" column="id">
    <generator class="assigned" />
  </id>
  <set name="Subs" inverse="true" lazy="true">
    <key column="other_id" />
    <one-to-many class="Sub" />
  </set>
</class>

以下无法对子查询内的连接子类进行连接:

Session.Query<Other>().Where(o => o.Subs.Any(s => s.Foo == "xyz"));

Sql

select
    other0_.id as id60_
from
    other_table other0_
where
    exists (
        select
            subs1_.id
        from
            sub_table subs1_
        where
            other0_.id=subs1_.other_id
            and subs1_1_.Foo=:p0
    );
:p0 = 'xyz' [Type: String (0)]

由于子查询中的 subs1_1_(例如 sub_table)没有 Foo,因此抛出 GenericADOException。 我必须在其他映射中执行某些操作才能使子查询中的子项与基项完全连接吗?

The following is an abstraction of an actual problem I'm having.

public class Base
{
    public virtual string Id { get; set; }
    public virtual string Foo { get; set; }
}

public class Sub : Base
{
    public virtual string Bar { get; set; }
    public virtual Other Other { get; set; }
}

public class Other
{
    public virtual string Id { get; set; }
    public virtual ICollection<Sub> Subs { get; set; }
}

mapping:

<class name="Base" table="base_table" xmlns="urn:nhibernate-mapping-2.2">
  <id name="Id" column="id">
    <generator class="assigned" />
  </id>
  <property name="Foo" column="Foo" />

  <joined-subclass name="Sub" table="sub_table">
    <key column="id" />
    <property    name="Bar"   column="Bar" />
    <many-to-one name="Other" column="other_id" />
  </joined-subclass>

</class>

<class name="Other" table="other_table" xmlns="urn:nhibernate-mapping-2.2">
  <id name="Id" column="id">
    <generator class="assigned" />
  </id>
  <set name="Subs" inverse="true" lazy="true">
    <key column="other_id" />
    <one-to-many class="Sub" />
  </set>
</class>

The following fails to do the join on the joined-subclass inside the subquery:

Session.Query<Other>().Where(o => o.Subs.Any(s => s.Foo == "xyz"));

Sql

select
    other0_.id as id60_
from
    other_table other0_
where
    exists (
        select
            subs1_.id
        from
            sub_table subs1_
        where
            other0_.id=subs1_.other_id
            and subs1_1_.Foo=:p0
    );
:p0 = 'xyz' [Type: String (0)]

A GenericADOException is thrown because subs1_1_ (e.g. sub_table) in the subquery doesn't have Foo.
Is there something I have to do in Other's mapping to cause the Subs to be fully joined with Base in the subquery?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迟到的我 2024-11-14 10:10:47

也许这是与连接子类映射相关的 linq 提供程序问题。该查询适用于每个层次结构的表。试试这个:

<class name="Base" table="base_table" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" column="id">
        <generator class="assigned" />
    </id>

    <discriminator column="Type" type="String" />

    <property name="Foo" column="Foo" />

    <subclass name="Sub" discriminator-value="Sub">
        <property    name="Bar"   column="Bar" />
        <many-to-one name="Other" column="other_id" />
    </subclass>
</class>

<class name="Other" table="other_table" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" column="id">
        <generator class="assigned" />
    </id>
    <set name="Subs" inverse="true" lazy="true">
        <key column="other_id" />
        <one-to-many class="Sub" />
    </set>
</class>

不幸的是,在所有情况下,加入的子类都不能被每个层次结构的表替换...

NH jira 中注册了一些看起来类似的问题(NH-2564NH-2491 )但不确定它们是否真的相关。

编辑:
HQL 也存在同样的问题:from Other o where isn't(from o.Subs s where s.Foo = 'xyz') 因此,这不是与 linq 提供程序相关的问题。

Maybe it is an linq provider issue related to joined subclass mapping. The query works well for table per hierarchy. Try this:

<class name="Base" table="base_table" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" column="id">
        <generator class="assigned" />
    </id>

    <discriminator column="Type" type="String" />

    <property name="Foo" column="Foo" />

    <subclass name="Sub" discriminator-value="Sub">
        <property    name="Bar"   column="Bar" />
        <many-to-one name="Other" column="other_id" />
    </subclass>
</class>

<class name="Other" table="other_table" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" column="id">
        <generator class="assigned" />
    </id>
    <set name="Subs" inverse="true" lazy="true">
        <key column="other_id" />
        <one-to-many class="Sub" />
    </set>
</class>

Unfortunatelly joined subclass cannot be replaced by table per hierarchy in all cases...

There are some issues registered in NH jira that looks similar (NH-2564, NH-2491) but not sure they are really related.

EDIT:
The same problem is with HQL: from Other o where exists(from o.Subs s where s.Foo = 'xyz') therefore it is not an issue related to linq provider.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文