NHibernate:选择一对多左连接 - 从父对象中取出最新的X.

时间:2014-12-29 16:18:35

标签: nhibernate fluent-nhibernate left-join queryover

我有以下对象:

Parent
   public virtual Guid Id { get; set; }
   public virtual DateTime TimeStamp { get; set; }
   public virtual IList<Child> Childs { get; set; }

Child
   public virtual Guid Id { get; set; }
   public virtual string Name { get; set; }

我使用Fluent将One To To映射如下:

.Override<Parent>(obj =>obj.HasMany(x => x.Childs)
                                .Cascade.All()
                                .Not.Inverse()
                                .Not.KeyNullable()
                                .Not.KeyUpdate())

我需要在TimeStamp之间的日期之间接触所有Child with Childs。

我正在尝试如下(maxCapacity为int):

QueryOver<Parent>().Where(x => x.TimeStamp > from)
            .And(x => x.TimeStamp < to).OrderBy(x => x.TimeStamp).Desc
            .Left.JoinQueryOver<Child>(x => x.Childs)
            .TransformUsing(new DistinctRootEntityResultTransformer())
            .Take(maxCapacity).List();

结果不是我的预期,因为 Take(maxCapacity)不在父结果上,而是包含父和子的总查询结果。

如何获取最新的X已转换的父行?

感谢。

1 个答案:

答案 0 :(得分:3)

我要去的地方是:

  • 加载根实体(Parent)和
  • 的列表
  • 让NHibernate懒惰加载他们的孩子 - 在单独的SQL查询中。

为了避免1 + N问题,我们可以使用智能映射功能:

19.1.5. Using batch fetching

  

NHibernate可以有效地使用批量提取,也就是说,如果访问一个代理(或集合),NHibernate可以加载几个未初始化的代理。批量提取是懒惰选择提取策略的优化。有两种方法可以调整批处理获取:在类和集合级别上。

     

更容易理解批量提取类/实体。想象一下,您在运行时遇到以下情况:您在一个ISession中加载了25个Cat实例,每个Cat都有一个对其所有者的引用,一个Person。 Person类使用代理映射,lazy =“true”。如果您现在遍历所有猫并在每个猫上调用cat.Owner,NHibernate将默认执行25个SELECT语句,以检索代理所有者......

所以,查询应该是这样的:

session.QueryOver<Parent>()
    .Where(x => x.TimeStamp > from)
    .And(x => x.TimeStamp < to).OrderBy(x => x.TimeStamp).Desc
    //.Left.JoinQueryOver<Child>(x => x.Childs)
    // .TransformUsing(new DistinctRootEntityResultTransformer())
    .Skip(start) // paging
    .Take(maxCapacity)
    .List<Parent>();

父映射应该是:

<class name="Parent">
    ...
    <bag name="Childs" batch-size="3">
        ...
    </bag>
</class>

请检查以下内容: