开发者

NHibernate - possible to fetch a collection after querying?

开发者 https://www.devze.com 2023-03-27 16:54 出处:网络
There\'s sooo much literature about fetching and eager loading when doing the actual query using .Fetch

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

精彩评论

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