使用NHibernate Castle Facility实现懒加载

5
我需要关闭由Castle的ISessionManager生成的ISession吗?如何处理这些ISession的事务?我对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个回答

6

1
你是否已经注册了SessionWebModule?http://www.mail-archive.com/castle-project-users@googlegroups.com/msg01663.html - Mauricio Scheffer
你正在使用ATM吗?你的事务类是否已经装饰了[Transactional]和[Transaction]?请发布一些代码。 - Mauricio Scheffer
代码库看起来不错。你能发布一个调用代码库的方法吗? - Mauricio Scheffer
尝试加入城堡项目用户组:http://groups.google.com/group/castle-project-users。在那里留下链接,这样他们就不必从头开始诊断了。 - Mauricio Scheffer
作为以后的参考,这是该线程的链接:http://groups.google.com/group/castle-project-users/browse_thread/thread/ca664d44fa1829cb - Mauricio Scheffer
显示剩余5条评论

0

我们使用带有using语句的事务来处理资源释放。

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

我认为这可能是由于未正确保存层次结构引起的。虽然我还没有测试过,但如果你希望访问父对象,也许可以通过保存父对象来解决这个问题。在保存之前将需要访问的信息放入局部变量中似乎可以纠正我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接