NHibernate - можно ли получить коллекцию после запроса? - PullRequest
1 голос
/ 11 августа 2011

Существует так много литературы о получении и быстрой загрузке при выполнении фактического запроса с использованием .Fetch

Но, как только у меня есть загруженный объект - с пустой коллекцией (потому что я решил не загружать запрос при запросевремя из-за побочного эффекта декартового произведения), могу ли я выбрать загрузку коллекции чуть позже, скажем, после того, как я произвел некоторую подкачку и у меня есть конкретный Список элементов?

что-то вроде:

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

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

Редактировать Дело в том, что я уже получаю 2 дочерние коллекции в запросе, что делает запрос и набор результатов уже достаточно крупными (см. Декартово-декартово произведение).Я хотел бы просмотреть результаты, получить список из 10, а затем, по желанию, вернуться в базу данных, чтобы заполнить свойства дочерней коллекции для постраничного (скажем, 10) результата.Это соображение производительности.

Ответы [ 2 ]

1 голос
/ 11 августа 2011

Оформить этот запрос

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

тогда nhibernate должен инициализировать коллекции на сущностях

EDIT:

для улучшения начального времени загрузки см. http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate

тогда вы можете сделать для примера

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()
0 голосов
/ 12 августа 2011

Я только что прочитал о фьючерсах и прогнозах в NHibernate, которые выглядят многообещающе как решение ... опубликую больше, когда узнаю об этом.

Это решение: http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate,, но оно мне все еще не нравится, так как сам мой запрос довольно дорогой (использует '% like% @ + paging), поэтому выполняется 3 или 4 раза только для загрузки коллекций кажется дорогим

Редактировать

Это то, что у меня есть. Посмотрите на сгенерированный sql, корректный sql запускается и возвращает ожидаемые результаты, но коллекции возвращаемых результатов равны нулю. Вы видите, чего не хватает?:

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();
    }
  }
...