【发布时间】:2014-02-10 17:45:33
【问题描述】:
我一直在使用通用存储库和 NHibernate,但在阻止内存泄漏/保持会话打开时遇到问题。
方法是
public IQueryable<TEntity> Find()
{
ISession session = _sessionFactory.OpenSession();
return session.Query<TEntity>();
}
显然这会使会话保持打开状态,但是当我使用以下功能时
public IQueryable<TEntity> Find()
{
using (ISession session = _sessionFactory.OpenSession())
{
return session.Query<TEntity>();
}
}
运行查询时会话关闭。
在查询运行后我是否可以处理会话??
这个方法的调用是这样的:
MyRepo repo = new MyRepo();
var list = repo.MyEntity.Find().Where(e => e.Id ==0).First();
//Need to dispose here????
这可以在调用方法不需要显式处理的情况下完成吗? IE。我想避免。
MyRepo repo = new MyRepo();
var list = repo.MyEntity.Find().Where(e => e.Id ==0).First();
repo.DisposeSession();
提前致谢。
编辑
这里是 repo 类
public NHibernateRepo<TEntity> : IRepo<TEntity> where TEntity : class
{
private readonly SessionFactory _sessionFactory;
public NHibernateRepo(SessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
}
public IQueryable<TEntity> Find()
{
ISession session = _sessionFactory.OpenSession();
return session.Query<TEntity>();
}
public void Add(TEntity entity)
{
using (ISession session = _sessionFactory.OpenSession())
{
session.Save(entity);
}
}
//Update and delete methods essentially same as add
}
这个会话管理似乎达到了我的需要,但我确信它一定有一些不安全的地方。有什么想法吗??
public class NHibernateRepo<TEntity> : IRepo<TEntity> where TEntity : class
{
private readonly ISessionFactory _sessionFactory;
private ISession _session;
public NHibernateRepo(Configuration configuration)
{
configuration.SetProperty("current_session_context_class", "thread_static");
_sessionFactory = configuration.BuildSessionFactory();
}
private ISession GetOpenSession()
{
if (_session == null)
{
if (!CurrentSessionContext.HasBind(_sessionFactory))
CurrentSessionContext.Bind(_sessionFactory.OpenSession());
_session = _sessionFactory.GetCurrentSession();
}
if (!_session.IsOpen)
{
_session = _sessionFactory.OpenSession();
}
return _session;
}
public IQueryable<TEntity> Find()
{
ISession session = GetOpenSession();
session.Clear();
return session.Query<TEntity>();
}
public void Update(TEntity value)
{
using (ISession session = GetOpenSession())
{
session.Transaction.Begin();
session.Update(value);
session.Transaction.Commit();
session.Flush();
session.Clear();
}
}
【问题讨论】:
-
问题不在于您的存储库,而在于您的会话管理。您是否根据请求打开闭幕会议? (这是一个网络项目吗)
-
它是一个 Windows Server\Win 窗体客户端项目,但理想情况下,我想在任何项目类型中使用相同的存储库样式。我将在我的问题上附上整个 Repo 课程。我对 Nhibernate 会话管理不太了解。
标签: c# session nhibernate memory-leaks dispose