NHibernate QueryOver - 选择连接表的子子节点的一个字段

时间:2013-10-08 11:26:07

标签: c# nhibernate join queryover

很难找到如何解决我的问题所以我在这里发布。

public class A
{
    public int IdA { get; set; }
    public List<AB> ABs { get; set; }
}

public class AB
{
    public A ObjectA { get; set; }
    public B ObjectB { get; set; }
}

public class B
{
    public int IdB { get; set; }
    public string Name { get; set; }
}

我想找一个QueryOver的方法来检索这个DTO的列表

public class DTO
{
   public int IdA { get; set; }
   public List<string> Names { get; set; }
}

正如您所看到的,我希望在ABs属性中找到对象B的所有“Name”属性。

如果你知道怎么做,可以帮助我吗?

2 个答案:

答案 0 :(得分:2)

有几种方法可以做到这一点,但我在中只知道 QueryOver。您可以将QueryOver查询视为几乎直接转换为SQL。如果您这样想,就不可能在一个步骤中填充List属性(您无法编写导致ID和项目“列表”的SQL查询,至少在没有使用某些项目的情况下聚合物)。

考虑到这一点,我认为最好定义一种新型的中间DTO。

public class FlattenedDTO 
{
    public int IdA { get; set; }
    public string Name { get; set; }
}

然后你写下你的查询,投射到FlattenedDTO。在我们选择FlattenedDTO s列表后,我们可以将它们分组到DTO s的新列表中:

B bAlias = null;
FlattenedDTO result = null;

session.QueryOver<A>()
    .JoinQueryOver<AB>(a => a.ABs)
    .JoinQueryOver(ab => ab.B, () => bAlias)
    .SelectList(list => list
        .Select(a => a.Id).WithAlias(() => result.IdA)
        .Select(() => bAlias.Name).WithAlias(() => result.Name))
    .TransformUsing(Transformers.AliasToBean<FlattenedDTO>())
    .List<FlattenedDTO>()
    // At this point the query has been run and we just need to group the results
    .GroupBy(dto => dto.IdA, dto => dto.Name)
    .Select(grp => new DTO { IdA = grp.Key, Names = grp.ToList() });

这将最终发出一个查询:

SELECT this_.IdA        as y0_,
       balias2_.Name    as y1_
FROM   [A] this_
       inner join [AB] ab1_
         on this_.Id = ab1_.IdA
       inner join [B] balias2_
         on ab1_.IdB = balias2_.Id

将结果分组到内存中。还有其他一些方法可以做到这一点,所以如果这不符合您的需求,请告诉我。

答案 1 :(得分:1)

你必须用表&amp;创建nhibernate映射。使用hbm.xml映射编写查询,如

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NSP.DataModel" namespace="NSP.DataModel.A">
  <class name="A" entity-name="SysA" table="A">
    <id name="IdA" column="id" type="Int32">
      <generator class="identity"/>
    </id>

    <bag name="DTO" inverse="true">
      <key column="IdA"/>
      <one-to-many entity-name="Names"/>
    </bag>

  </class>
</hibernate-mapping>