NHibernate - отказавший для ленивой инициализации набора роли

Краткие заголовки делают URL более удобным для пользователя, и Вы знаете, что ожидать при щелчке на ссылку. Поисковые системы, такие как Google, оцените страницы выше, если searchword находится в URL.

20
задан jamesaharvey 12 December 2009 в 14:36
поделиться

2 ответа

Проблема в том, что вы создаете, а также закрываете сеанс в своих моделях GetById метод. (оператор using закрывает сеанс) Сеанс должен быть доступен в течение всей бизнес-транзакции.

Есть несколько способов добиться этого. Вы можете настроить NHibernate для использования метода GetCurrentSession фабрик сеансов. См. это на nhibernate.info или это сообщение в Code Project .

public SomeModel GetById(Guid id)
{
    // no using keyword here, take the session from the manager which
    // manages it as configured
    ISession session = NHibernateSessionManager.Instance.GetSession();
    return session.Get<SomeModel >(id);
}

Я не использую это. Я написал свою собственную службу транзакций, которая позволяет следующее:

using (TransactionService.CreateTransactionScope())
{
  // same session is used by any repository
  var entity = xyRepository.Get(id);

  // session still there and allows lazy loading
  entity.Roles.Add(new Role());

  // all changes made in memory a flushed to the db
  TransactionService.Commit();
}

Как бы вы ее не реализовали, сеансы и транзакции должны существовать столько же, сколько бизнес-транзакция (или системная функция). Если только вы не можете полагаться ни на изоляцию транзакций, ни на откат всего этого.

21
ответ дан 30 November 2019 в 00:27
поделиться

You need to eagerly load the SomeOtherModel collection if you intend to use it before closing the session:

using (ISession session = NHibernateSessionManager.Instance.GetSession())
{
    return session
        .CreateCriteria<SomeModel>()
        .CreateCriteria("SomeOtherModel", JoinType.LeftOuterJoin)
        .Add(Restrictions.Eq(Projections.Id(), id))
        .UniqueResult<SomeModel>();
}

By default FluentNHibernate uses lazy loading for collection mappings. Another option is to modify this default behavior in your mapping:

HasMany(x => x.SomeOtherModel)
    .KeyColumns.Add("key_id").AsBag().Not.LazyLoad();

Note that if you do this SomeOtherModel will be eagerly loaded (using an outer join) every time you load the parent entity which might not be want you want. In general I prefer to always leave the default lazy loading at the mapping level and tune my queries depending on the situation.

10
ответ дан 30 November 2019 в 00:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: