2010-06-29 4 views
2

Я переношу свое веб-приложение mvc, чтобы использовать Nhibernate Facility для управления Nhibernate сеансы.Замок Windsor Nhibernate Facility Lazy loading

Я столкнулся с этой странной проблемой;

Когда я зарегистрировать SessionWebModule под web.config/HttpModules через:

<add name="NHibernateSessionWebModule" 
type="Castle.Facilities.NHibernateIntegration.Components.Web.SessionWebModule, 
Castle.Facilities.NHibernateIntegration" /> 

система не в состоянии ленивых объекты нагрузки. У меня нет исключения сеанса.

Если я не добавляю это в web.config, ленивая загрузка работает нормально. Все части от этого, кажется, все в порядке до регистрации Windsor контейнер и регистрация Nhibernate Facility идет. Nhibernate Объект может предоставить менеджер сеанса, а контейнер Windsor - , способный разрешать объекты.

Конечно, без SessionWebModule Nhibernate Facility почти бесполезен для меня, поскольку в этой ситуации он не может правильно управлять сеансами. Я вижу, что datareader имеет все открытые исключения типа, которые являются . Не хорошо.

Я застрял, и мне нужно срочно преодолеть эту проблему. Я буду ценю любую помощь от вас.

Я включаю ниже некоторых разделов моей конфигурации и кода в дать больше информации

Web.config:

<castle> 
     <facilities> 
      <facility id="nhibernatefacility" isWeb="false" 
type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, 
Castle.Facilities.NHibernateIntegration"> 
       <factory id="nhibernate.factory"> 
        <settings> 
         <item 
key="connection.provider">NHibernate.Connection.DriverConnectionProvider</ 
item> 
         <item 
key="connection.driver_class">NHibernate.Driver.SqlClientDriver</item> 
         <item key="connection.connection_string">Data 
Source=zzz;Database=xxx;Trusted_Connection=True;</item> 
         <item 
key="dialect">NHibernate.Dialect.MsSql2005Dialect</item> 
         <item 
key="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, 
NHibernate.ByteCode.LinFu</item> 
         </settings> 
        <assemblies> 
         <assembly>AppWeb.Domain</assembly> 
        </assemblies> 
       </factory> 
      </facility> 
     </facilities> 
    </castle> 

<system.webServer> 
     <validation validateIntegratedModeConfiguration="false" /> 
     <modules runAllManagedModulesForAllRequests="true"> 
       <add name="NHibernateSessionWebModule" 
type="Castle.Facilities.NHibernateIntegration.Components.Web.SessionWebModule, 
Castle.Facilities.NHibernateIntegration" /> 
     </modules> 
</sytem.webServer> 

Global.asax

public class MvcApplication : System.Web.HttpApplication, 
IContainerAccessor 
    { 
     private static IWindsorContainer container; 

     public IWindsorContainer Container 
     { 
      get { return container; } 
     } 

     void Application_Error(Object sender, EventArgs e) 
     { 
      Logger.Error(Server.GetLastError()); 
     } 

     public static void RegisterRoutes(RouteCollection routes) 
     { 
      #region Ignores 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
      routes.IgnoreRoute("admin/{*url}"); 
      #endregion 

      routes.MapRoute(
       "Default", 
       "{controller}/{action}/{id}", 
       new { controller = "Home", action = "Main", id = "" }, 
       new { controller = @"[^\.]*" } 
      ); 
     } 

     protected void Application_Start() 
     { 
      RegisterRoutes(RouteTable.Routes); 
      log4net.Config.XmlConfigurator.Configure(); 
      SetupWindsor(); 
     } 

     private void SetupWindsor() 
     { 
      container = new WindsorContainer(new XmlInterpreter()); 

      container.Register(
         AllTypes 
          .FromAssemblyContaining<UserRepository>() 
          .Where(t => t.Name.EndsWith("Repository", 
StringComparison.Ordinal)) 
          .WithService 
          .FirstInterfaceOnType() 
          .Configure(r => 
r.LifeStyle.PerWebRequest), 

AllTypes.FromAssembly(Assembly.GetExecutingAssembly()) 
          .BasedOn<IController>() 
          .Configure(c => 
c.LifeStyle.PerWebRequest), 

        ); 
        //.AddFacility<TransactionFacility>(); 

      ControllerBuilder.Current.SetControllerFactory(new 
WindsorControllerFactory(container)); 
     } 
    } 

Ленивая загрузка исключение:

[LazyInitializationException: In itializing [AppWeb.Domain.City # 31135] - не удалось инициализировать прокси - нет Session] NHibernate.Proxy.AbstractLazyInitializer.Initialize() +138 NHibernate.Proxy.AbstractLazyInitializer.GetImplementation() +37 NHibernate.ByteCode.. LinFu.LazyInitializer.Intercept (InvocationInfo информация) +72 CityProxy.get_Name() +143 ASP.views_tour_filters_ascx .__ Render__control1 (HtmlTextWriter __w, управления parameterContainer) в C: \ Wwwroot \ AppWeb \ AppWeb.Web \ Views \ Tour \ Filters.ascx: 14 System.Web.UI.Control.RenderChildrenInternal (HtmlTextWriter writer, ICollection children) +256 System.Web.UI.Control.RenderChildren (HtmlTextWriter writer) +19 System.Web.UI.Control.Render (HtmlTextWriter писатель) +10 System.Web.UI.Control.RenderControlInternal (HtmlTextWriter писатель, ControlAdapter адаптер) +27 System.Web.UI.Control.RenderControl (HtmlTextWriter писатель, ControlAdapter адаптер) +99 System.Web.UI.Control.RenderControl (HtmlTextWriter писатель) +25 System.Web.UI.Control.RenderChildrenInternal (HtmlTextWriter писатель, ICollection детей) +134 System.Web.UI .Control.RenderChildren (HtmlTextWriter writer) +19 System.Web.UI.Page.Render (HtmlTextWriter writer) +29 System.Web.Mvc.ViewPage.Render (HtmlTextWriter писатель) +59 System.Web.UI.Control.RenderControlInternal (HtmlTextWriter писатель, ControlAdapter адаптер) +27 System.Web.UI.Control.RenderControl (HtmlTextWriter писатель, ControlAdapter адаптер) +99 системы. Web.UI.Control.RenderControl (HtmlTextWriter писатель) +25 System.Web.UI.Page.ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1266

ответ

3

Это дизайн. Вы должны держать свою сессию открытой.

Если вы работаете в Интернете, я предлагаю вам открыть сеанс в начале запроса и закрыть его в конце.

Получить образцы из этой статьи: http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

+1

Im помощью «NHibernate фонда», который предполагается обрабатывать все управление сессии ... – kaivalya

+2

Может быть, но в вашем коде, вы отчуждать сеанс явным образом с помощью «Использование». – 2010-06-29 13:09:49

+1

Nhibernate Facility имеет механизм кэширования, который кэширует объекты и повторно использует их в том же контексте. Я обновил свой вопрос, узнав, что моя проблема не связана с операциями using. Lazy loading не работает независимо от операторов using, как только я регистрирую требуемый SessionWebModule – kaivalya

0

Если вы используете MVC, я использую фильтр действий, чтобы закрыть NHibernate сессий

public class NHibernateSessionAttribute : ActionFilterAttribute 
{ 
    public NHibernateSessionAttribute() 
    { 
     Order = 100; 
    } 


    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if (filterContext.IsChildAction) return; 

     SessionSource.EndContextSession(); 
    } 
} 

SessionSource где я управлять созданием своих сессий ... и метод SessionSource.EndContextSession(), по существу называет:

public static void EndContextSession() 
    { 
     var session = CurrentSessionContext.Unbind(Factory); 
     if (session != null && session.IsOpen) 
     { 
      try 
      { 
       if (session.Transaction != null && session.Transaction.IsActive) 
       { 
        // an unhandled exception has occurred and no db commit should be made 
        session.Transaction.Rollback(); 
       } 
      } 
      finally 
      { 
       session.Close(); 
       session.Dispose(); 
      } 
     } 
    } 
0

Я верю, вы должны установить атрибут истинного isWeb :

<facility id="nhibernatefacility" isWeb="true" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration"> 
+1

, почему вы добавляете этот атрибут? что это изменится? – toxicate20

Смежные вопросы