【问题标题】:Is this the right way of using ThenFetch() to load multiple collections?这是使用 ThenFetch() 加载多个集合的正确方法吗?
【发布时间】:2011-03-24 19:15:06
【问题描述】:

我正在尝试使用NHibernate 3 alpha 1 急切地加载所有集合。我想知道这是否是使用 ThenFetch() 的正确方法?

具有复数名称的属性是集合。其他的只是一个对象。

            IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
            from mi in db
            where mi.RunDate == runDate
            select mi).Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.PrimaryOwners)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.SecondaryOwners)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.Predecessors)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.Function)
                .Fetch(mi => mi.Milestone)
                .ThenFetchMany(m => m.Jobs)
                .ThenFetch(j => j.Source)
                ;

我想在NHibernate forums 中问这个问题,但不幸的是,我所在的地方禁止访问谷歌群组。我知道Fabio 在这里,也许NHibernate 团队的人可以对此有所了解? 谢谢

【问题讨论】:

    标签: nhibernate orm linq-to-nhibernate fetching-strategy


    【解决方案1】:
            IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
            from mi in db
            where mi.RunDate == runDate
            select mi);
    
    var fetch = milestoneInstances.Fetch(f => f.Milestone);
    fetch.ThenFetch(f => f.PrimaryOwners);
    fetch.ThenFetch(f => f.SecondaryOwners);
    //...
    

    【讨论】:

      【解决方案2】:

      显然,在这种情况下没有“正确”的方式来使用ThenFetch。您的示例运行良好,但生成的 SQL 包含许多与 Milestone 的连接,这是不对的。

      使用IQueryOver 代替IQueryable 允许您在Fetch 中使用complex syntax

      Fetch(p => p.B) 
      Fetch(p => p.B.C) // if B is not a collection ... or 
      Fetch(p => p.B[0].C) // if B is a collection ... or 
      Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method) 
      

      所以你的情况是:

      query // = session.QueryOver<X>()
          .Fetch(mi => mi.Milestone).Eager
          .Fetch(mi => mi.Milestone.PrimaryOwners).Eager
          .Fetch(mi => mi.Milestone.SecondaryOwners).Eager
          .Fetch(mi => mi.Milestone.Predecessors).Eager
          .Fetch(mi => mi.Milestone.Function).Eager
          .Fetch(mi => mi.Milestone.Jobs).Eager
          .Fetch(mi => mi.Milestone.Jobs.First().Source).Eager
      

      【讨论】:

        【解决方案3】:

        正如 leora 所说,确保在获取您使用的子集合时

        FetchMany()
        
        ThenFetchMany()
        

        一个新的 Fetch 应该从根目录获取,但这并不总是发生。有时您需要将它们创建为单独的查询或使用 Criteria Futures 来批量获取多个。

        【讨论】:

          【解决方案4】:

          您缺少的一件事是您应该使用 FetchMany() 和 ThenFetchMany() 是子属性是一个集合。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-10-03
            • 1970-01-01
            • 1970-01-01
            • 2012-05-11
            • 2018-12-31
            • 2021-04-29
            相关资源
            最近更新 更多