Ленивая загрузка с NHibernate Castle Facility

Должен ли я закрыть ISessionкоторые генерируются Каслом ISessionManager для NHibernate? Как мне обрабатывать транзакции с этими ISession"S? Я все еще довольно новичок в NHibernate.

Изменить: я хотел бы иметь ленивую загрузку, но я получаю это сообщение:

При инициализации [не удалось лениво инициализировать коллекцию ролей: ни один сеанс или сеанс не был закрыт "

Вот мой общий репозиторий, который я наследую для реализации конкретных экземпляров.

[Transactional]
public class Repository<TKey, TModel>
    : IRepository<TKey, TModel>
    where TKey : IComparable
    where TModel : class
{
    private readonly ISessionManager _sessionManager;

    protected ISession Session { get { return _sessionManager.OpenSession(); } }

    public Repository(ISessionManager sessionManager)
    {
        _sessionManager = sessionManager;
    }
    #region IRepository<TKey,TModel> Members

    public virtual TModel Select(TKey key)
    {
        using (var session = _sessionManager.OpenSession())
        {
            return session.Get<TModel>(key);
        }
    }

    public virtual IList<TModel> SelectWhere(Func<TModel, bool> query)
    {
        using (var session = Session)
        {
            return session.Linq<TModel>().Where(query).ToList();
        }
    }

    public virtual TModel Single(Func<TModel, bool> query)
    {
        using (var session = Session)
        {
            return session.Linq<TModel>().SingleOrDefault(query);
        }
    }

    public virtual TModel First(Func<TModel, bool> query)
    {
        using (var session = Session)
        {
            return session.Linq<TModel>().FirstOrDefault(query);
        }
    }

    public virtual IList<TModel> All()
    {
        using (var session = Session)
        {
            return session.Linq<TModel>().ToList();
        }
    }

    [Transaction(TransactionMode.Requires)]
    public virtual void Store(TModel entity)
    {
        using (var session = Session)
        {
            session.SaveOrUpdate(entity);
        }
    }

    [Transaction(TransactionMode.Requires)]
    public virtual void Store(IEnumerable<TModel> entities)
    {
        using (var session = Session)
        {
            foreach (TModel entity in entities)
                session.SaveOrUpdate(entity);
        }
    }


    [Transaction(TransactionMode.Requires)]
    public virtual void Remove(TModel entity)
    {
        using (var session = Session)
        {
            session.Delete(entity);
        }

    }

    public virtual void Remove(Func<TModel, bool> query)
    {
        IEnumerable<TModel> entities = SelectWhere(query);
        Remove(entities);
    }

    [Transaction(TransactionMode.Requires)]
    public virtual void Remove(IEnumerable<TModel> entities)
    {
        using (var session = Session)
        {
            foreach (TModel entity in entities)
                session.Delete(entity);
        }
    }

    #endregion
}

public class Repository<TModel>
    : Repository<Guid, TModel>, IRepository<TModel>
    where TModel : class
{
    public Repository(ISessionManager sessionManager) : base(sessionManager) { }
}

public class Repository
    : Repository<ulong, object>, IRepository
{
    public Repository(ISessionManager sessionManager) : base(sessionManager) { }
}

Вот пример вызова этого хранилища:

IUserRepository userRepository = new UserRepository(); // This is actually provided by my IoC

var users = userRepository.All();
foreach (var user in Users)
{
    foreach (var picture in user.Pictures)
    {
        // I get exceptions when I do stuff like this.
    }
}

2 ответа

Да, всегда распоряжаться ISession, Смотрите документы на ISessionManager использование

Для транзакций рассмотрите возможность использования средства автоматической транзакции.

SessionManager поддерживает ATM, поэтому он будет ISession разумно, когда это необходимо, принимая во внимание транзакции, даже когда вы, по-видимому, распорядились ISession,

Вот пример быстрого и грязного приложения, в котором используется ASP.NET MVC + средство автоматической транзакции Castle + средство NHibernate

Мы используем транзакции с использованием выписок для обработки утилизации.

public void Save<K>(K entity)
        {

            if (entity == null)
                throw new ArgumentNullException("item", "The item being saved cannot be null.");

            using (ISession session = GetSession())
            {
                using (ITransaction tx = session.BeginTransaction())
                {
                    session.SaveOrUpdate(entity);
                    tx.Commit();
                }
            }
        }

Я все равно получу ошибку отложенной загрузки, если получу доступ к объектам после внесения изменений в то же действие. Я исправил ошибку, не имея доступа к объектам после сохранения. Вот объяснение: NHibernate.LazyInitializationException

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

Другие вопросы по тегам