开发者

NHibernate - possible to fetch a collection after querying?

There's sooo much literature about fetching and eager loading when doing the actual query using .Fetch

But, once I have a loaded entity - with an empty collection (because I chose not to eager load at query time due to the cartesian product side-effect), can I choose to load a collection a bit later on, say after I've done some paging and I have a concrete List of items?

something like:

var list = (some linq over Session.Query<Entity>)
.Take(10).Skip(2)
.Fetch(x => x.MyCollection)
.ToList();

Session.Fetch<Entity>(list, l => l.OtherCollection);

Edit The point is - i'm already fetching 2 child collections in the Query - makes the query and result set quite sizeable already (see nhibernate Cartesian product). I'd like page the results, get a list of 10 then optionally go back to the database to populate child collection properties of the pa开发者_高级运维ged (10, say) result. This is a performance consideration.


Issue this query

/*we dont need the result*/Session.QueryOver<Entity>()
    .Where(x => x.Id.IsIn(list.Select(l => l.Id)))
    .Fetch(l => l.OtherCollection)
    .ToList();

then nhibernate should initialize the collections on the Entities

EDIT:

to improve initial loading time see http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate

then you can do for exmaple

var results = (some linq over Session.Query<Entity>)
    .Take(10).Skip(2)
    .ToList();

var q = Session.QueryOver<Entity>()
    .Where(x => x.Id.IsIn(list.Select(l => l.Id)))
    .Fetch(l => l.MyCollection)
    .ToFuture();

Session.QueryOver<Entity>()
    .Where(x => x.Id.IsIn(list.Select(l => l.Id)))
    .Fetch(l => l.OtherCollection)
    .ToFuture();

Session.QueryOver<Entity>()
    .Where(x => x.Id.IsIn(list.Select(l => l.Id)))
    .Fetch(l => l.ThirdCollection)
    .ToFuture();

return q.ToList()


I've just gone off to read about futures and projections in NHibernate which look promising as a solution...will post more when I find out about it.

This is a solution: http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate, but I still do not like it, as my query itself is quite expensive (uses '%like%@ + paging), so executing 3 or 4 times just to load collections seems expensive

Edit

This is what I have. Lookign at the sql generated, the correct sql is being run and returning expected results, but the collections on the returned results are null. Can you see what's missing?:

public List<Company> CompaniesForLoggedInUser(int pageSize, int pageNumber)
    {
      var list =
        QueryForCompaniesFor(SecurityHelper.LoggedInUsername)
          .Page(pageNumber, pageSize)
          .ToList()
          .FetchCompanyCollections(Session);
      return list;
    }

internal static class CompanyListExtensions
  {
    internal static List<Company> FetchCompanyCollections(this List<Company> companies, ISession session)
    {
      var ids = companies.Select(l => l.Id).ToArray();

      session.QueryOver<Company>()
        .Where(x => x.Id.IsIn(ids))
        .Fetch(l => l.Properties).Eager()
        .Future();

      return session.QueryOver<Company>()
        .Where(x => x.Id.IsIn(ids))
        .Fetch(l => l.UserAccessList).Eager()
        .Future()
        .ToList();
    }
  }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜