我已经将NHibernate会话包装在我自己的IDataContext中。我的NHibernate实现如下:
public class NHibernateDataContext : IDataContext {
private readonly ISession _session;
public NHibernateDataContext(ISession session) {
_session = session;
Begin();
}
public IRepository<T> Repository<T>() where T : class {
return new NHibernateRepository<T>(_session);
}
public void Begin() {
if (!_session.Transaction.IsActive)
_session.BeginTransaction();
}
public void Commit() {
if (_session.Transaction.IsActive)
_session.Transaction.Commit();
}
public void Dispose() {
_session.Close();
}
}
public class NHibernateRepository<T> : IRepository<T> where T : class {
private readonly ISession _session;
public NHibernateRepository(ISession session) {
_session = session;
}
public IQueryable<T> GetAll() {
return _session.Query<T>();
}
public T GetByID(int id) {
return _session.Get<T>(id);
}
public void Insert(T entity) {
_session.SaveOrUpdate(entity);
}
public void Delete(T entity) {
_session.Delete(entity);
}
}
使用Microsoft Unity i,然后通过说:
注册// Configure the container
container.RegisterType<ISessionFactory>(new ContainerControlledLifetimeManager(), new InjectionFactory(c => {
return CreateSessionFactory();
}));
container.RegisterType<ISession>(new InjectionFactory(c => {
var sessionFactory = container.Resolve<ISessionFactory>();
return sessionFactory.OpenSession();
}));
container.RegisterType<IDataContext, NHibernateDataContext>(new PerRequestLifetimeManager<IDataContext>());
到目前为止一直很好,但我的应用程序需要生成一些大型报告。我发现由于第一级缓存膨胀,它们会以指数方式变慢。我理解IStatelessSession接口允许我这样做。
如何重构我的应用程序,以便在查询某些数据时可以轻松使用IStatelessSession而不是ISession?请注意,对于每个请求,我仍然希望打开一个ISession,但只在我需要时才能使用IStatelessSession。
我很感激帮助。感谢
答案 0 :(得分:3)
IStatelessSession行为与ISession显着不同:
无状态会话也不实现第一级缓存 与任何二级缓存交互,也不实现 事务性后写或自动脏检查,也不做 操作级联到关联的实例。集合被忽略 无国籍的会议。通过无状态会话执行的操作 绕过NHibernate的事件模型和拦截器。无国籍会议 由于缺少a,很容易受到数据混叠效应的影响 第一级缓存。
你可以通过定期调用ISession.Clear
来对抗第一级缓存膨胀,比如每500个已加载的对象。否则,您可以创建一个新的“上下文”(但要为意外行为做好准备)。
public class NHibernateStatelessDataContext : IDataContext {
private readonly IStatelessSession _session;
...
}