Примечание. Теперь, когда я набрал это, я должен извиниться за сверхдолжный вопрос, однако, я думаю, что весь представленный здесь код и информация имеют какое-то значение.
Хорошо, я получаю странные ошибки "Session Is Closed", в случайных точках моего приложения веб-форм ASP.NET. Однако сегодня это происходит в одном и том же месте снова и снова. Я почти уверен, что ничто не избавляет или не закрывает сессию в моем коде, так как биты кода, которые используются, хорошо содержатся вне всего остального кода, как вы увидите ниже.
Я также использую ninject как мой IOC, который может/не быть важным.
Итак, сначала мои классы SessionFactoryProvider
и SessionProvider
:
SessionFactoryProvider
public class SessionFactoryProvider : IDisposable
{
ISessionFactory sessionFactory;
public ISessionFactory GetSessionFactory()
{
if (sessionFactory == null)
sessionFactory =
Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2005.ConnectionString(p =>
p.FromConnectionStringWithKey("QoiSqlConnection")))
.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf<JobMapping>())
.BuildSessionFactory();
return sessionFactory;
}
public void Dispose()
{
if (sessionFactory != null)
sessionFactory.Dispose();
}
}
SessionProvider
public class SessionProvider : IDisposable
{
ISessionFactory sessionFactory;
ISession session;
public SessionProvider(SessionFactoryProvider sessionFactoryProvider)
{
this.sessionFactory = sessionFactoryProvider.GetSessionFactory();
}
public ISession GetCurrentSession()
{
if (session == null)
session = sessionFactory.OpenSession();
return session;
}
public void Dispose()
{
if (session != null)
{
session.Dispose();
}
}
}
Эти два класса связаны с Ninject следующим образом:
NHibernateModule
public class NHibernateModule : StandardModule
{
public override void Load()
{
Bind<SessionFactoryProvider>().ToSelf().Using<SingletonBehavior>();
Bind<SessionProvider>().ToSelf().Using<OnePerRequestBehavior>();
}
}
и насколько я могу сказать работу, как ожидалось.
Теперь мой BaseDao<T>
класс:
BaseDao
public class BaseDao<T> : IDao<T> where T : EntityBase
{
private SessionProvider sessionManager;
protected ISession session { get { return sessionManager.GetCurrentSession(); } }
public BaseDao(SessionProvider sessionManager)
{
this.sessionManager = sessionManager;
}
public T GetBy(int id)
{
return session.Get<T>(id);
}
public void Save(T item)
{
using (var transaction = session.BeginTransaction())
{
session.SaveOrUpdate(item);
transaction.Commit();
}
}
public void Delete(T item)
{
using (var transaction = session.BeginTransaction())
{
session.Delete(item);
transaction.Commit();
}
}
public IList<T> GetAll()
{
return session.CreateCriteria<T>().List<T>();
}
public IQueryable<T> Query()
{
return session.Linq<T>();
}
}
Что связано в Ninject так:
DaoModule
public class DaoModule : StandardModule
{
public override void Load()
{
Bind(typeof(IDao<>)).To(typeof(BaseDao<>))
.Using<OnePerRequestBehavior>();
}
}
Теперь веб-запрос, вызывающий это, когда я сохраняю объект, это произошло не до тех пор, пока я не внес некоторые изменения модели сегодня, однако изменения в моей модели не изменили код доступа к данным в любом случае. Хотя это изменило несколько сопоставлений NHibernate (я могу опубликовать их тоже, если кому-то интересно)
Насколько я могу судить, вызывается BaseDao<SomeClass>.Get
, тогда вызывается BaseDao<SomeOtherClass>.Get
, тогда вызывается BaseDao<TypeImTryingToSave>.Save
.
это третий вызов в строке в Save()
using (var transaction = session.BeginTransaction())
который терпит неудачу с "Сессия закрыта!" или, скорее, исключение:
Session is closed!
Object name: 'ISession'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ObjectDisposedException: Session is closed!
Object name: 'ISession'.
И действительно, после прокрутки на Debugger показано, что в третий раз сеанс запрашивается из SessionProvider
, он действительно закрыт и не подключен.
Я подтвердил, что Dispose
на моем SessionFactoryProvider
и на моем SessionProvider
вызывается в конце запроса, а не до того, как вызов Save
сделан на моем Dao.
Итак, теперь я немного застрял. Несколько сообразительных моментов.
- Я делаю что-то явно неправильно?
- Неужели NHibernate закрывает сеансы без моего запроса?
- Любые обходные пути или идеи о том, что я могу сделать?
Заранее спасибо