Я уже некоторое время использую NHibernate и время от времени обнаруживаю, что если я попытаюсь запросить две страницы одновременно (или как можно ближе), это иногда приводит к ошибке. Поэтому я предположил, что это потому, что мое управление сеансами не было поточно-ориентированным.
Я думал, что это был мой класс, поэтому я попытался использовать метод, отличный от этого сообщения в блоге http://pwigle.wordpress.com/2008/11/21/nhibernate-session-handling-in-aspnet-the-easy-way/, но у меня все еще возникают те же проблемы. Фактическая ошибка, которую я получаю:
Server Error in '/AvvioCMS' Application.
failed to lazily initialize a collection, no session or session was closed
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: NHibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
Либо тот, либо нет хранилища данных, но это главный виновник.
Я разместил свой класс управления сессиями ниже, кто-нибудь может определить, почему у меня могут быть эти проблемы?
public interface IUnitOfWorkDataStore
{
object this[string key] { get; set; }
}
public static Configuration Init(IUnitOfWorkDataStore storage, Assembly[] assemblies)
{
if (storage == null)
throw new Exception("storage mechanism was null but must be provided");
Configuration cfg = ConfigureNHibernate(string.Empty);
foreach (Assembly assembly in assemblies)
{
cfg.AddMappingsFromAssembly(assembly);
}
SessionFactory = cfg.BuildSessionFactory();
ContextDataStore = storage;
return cfg;
}
public static ISessionFactory SessionFactory { get; set; }
public static ISession StoredSession
{
get
{
return (ISession)ContextDataStore[NHibernateSession.CDS_NHibernateSession];
}
set
{
ContextDataStore[NHibernateSession.CDS_NHibernateSession] = value;
}
}
public const string CDS_NHibernateSession = "NHibernateSession";
public const string CDS_IDbConnection = "IDbConnection";
public static IUnitOfWorkDataStore ContextDataStore { get; set; }
private static object locker = new object();
public static ISession Current
{
get
{
ISession session = StoredSession;
if (session == null)
{
lock (locker)
{
if (DBConnection != null)
session = SessionFactory.OpenSession(DBConnection);
else
session = SessionFactory.OpenSession();
StoredSession = session;
}
}
return session;
}
set
{
StoredSession = value;
}
}
public static IDbConnection DBConnection
{
get
{
return (IDbConnection)ContextDataStore[NHibernateSession.CDS_IDbConnection];
}
set
{
ContextDataStore[NHibernateSession.CDS_IDbConnection] = value;
}
}
}
А фактический магазин, которым я пользуюсь, таков:
public class HttpContextDataStore : IUnitOfWorkDataStore
{
public object this[string key]
{
get { return HttpContext.Current.Items[key]; }
set { HttpContext.Current.Items[key] = value; }
}
}
Я инициализирую SessionFactory в Application_Start с:
NHibernateSession.Init(new HttpContextDataStore(), new Assembly[] {
typeof(MappedClass).Assembly});
Обновление
Привет, ребята, спасибо за ваш совет, я попробовал несколько разных вещей, чтобы попытаться упростить код, но я все еще сталкиваюсь с теми же проблемами, и у меня может быть идея почему.
Я создаю сеанс для каждого запроса по мере необходимости, но в моем global.asax я удаляю сеанс в Application_EndRequest. Однако я обнаружил, что Application_EndRequest запускается более одного раза, пока я нахожусь в состоянии отладки в конце загрузки страницы. Я подумал, что событие должно запускаться только один раз в самом конце запроса, но если это не так, и некоторые другие элементы пытаются использовать Сессию (на что жалуется ошибка) по какой-то странной причине, которая могла бы быть моей проблемой, и Сессия все еще поточно-безопасна, она просто удаляется на ранний срок.
У кого-нибудь есть идеи? Я сделал Google и увидел, что сервер разработки VS вызывает подобные проблемы, но я запускаю его через IIS.