我是否必须关闭Castle的ISession
为NHibernate生成的ISessionManager
?如何处理那些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.
}
}
答案 0 :(得分:6)
是的,始终处置ISession
。请参阅the docs on ISessionManager
usage。
对于交易,请考虑使用Automatic Transaction Facility。
SessionManager is ATM-aware所以它会在需要时巧妙地处理ISession
,将交易考虑在内,即使您显然已经处理了ISession
。
Here's a quick & dirty sample app使用ASP.NET MVC + Castle自动事务处理工具+ NHibernate工具
答案 1 :(得分: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
我认为这是因为没有正确保存层次结构。我还没有对它进行过测试,但是如果您希望访问它们,可能会保存父对象将解决问题。在保存之前保存到局部变量之后,简单地输入我需要访问的信息似乎可以纠正我的问题。