会话已关闭对象名称:'ISession'.at NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed() - 如何阻止会话过早关闭

Neo*_*eto 6 c# mysql nhibernate ninject fluent-nhibernate

我在MySQL的MVC C#应用程序中使用NHibernate.我想让多个用户访问会话.我一直在使用.InRequestScope()我的会话,但我仍然得到:

System.ObjectDisposedException:会话已关闭!对象名称:'ISession'.在NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed()*

...或者当我的同事都导航到同时访问服务的同一页面时,DataReader错误.

我的IMasterSessionSource注入

Bind<IMasterSessionSource>().To<GeneralMasterSessionSource()
                            .InRequestScope();
Run Code Online (Sandbox Code Playgroud)

我的IContentService是我的映射得到服务的地方

        //ContentService Bingings
        Bind<IContentService>().To<ContentService>().InRequestScope();
        Bind<ISession>()
            .ToMethod(
                context =>
                    context.Kernel.Get<IMasterSessionSource>()
                        .ExposeConfiguration()
                        .BuildSessionFactory()
                        .OpenSession()
            )
            .WhenInjectedInto<IContentService>()
            .InRequestScope();
Run Code Online (Sandbox Code Playgroud)

contentService的

public interface IContentService
    {
        IQueryable<Question> Questions{ get; }
    }


 public class ContentService : IContentService
    {
        private readonly ISession _session;

        public ContentService(ISession session)
        {
            _session = session;
        }

        public IQueryable<Question> Questions
        {
            get { return _session.Query<Question>(); }
        }
    }
Run Code Online (Sandbox Code Playgroud)

DetailsS​​ervice

 public interface IDetailsService
    {
        IEnumerable<Question> PullQuestions();
    }

 public class DetailsService : IDetailsService
    {
        private readonly IContentService _contentService;


        public GeneralService(IContentService contentService)
        {
            _contentService = contentService;
        }

        public IEnumerable<Question> PullQuestions()
        {
            var result = _contentService.Questions;
            return result;
        }
}
Run Code Online (Sandbox Code Playgroud)

CONTROLLER

public class Test: Controller
    {

        private readonly IContentService _contentService;
        private readonly IGeneralService _generalService;

        public CollegeController(IContentService contentService, IDetailsService detailsService)
        {
            _contentService = contentService;
            _detailsService = detailsService;
        }

        public ActionResult Index()
        {
            {
                var model = new HomePageContent
                {
                    Questions = _detailsService.PullQuestions().ToList();
                };
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

模型

 public class HomePageContent
    {
        public IEnumerable<Question> Questions { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

视图

foreach(var question in Model.Questions){
@Html.Raw(question.Question)
}
Run Code Online (Sandbox Code Playgroud)

因此,对于访问该页面的单个用户.一切正常.但是当mutliple用户访问同一页面时,每个都会得到错误:

{"已经有一个与此Connection关联的开放DataReader必须先关闭."} {"已经有一个与此Connection关联的开放DataReader必须先关闭."} {"数据读取器中没有当前查询"} {"数据读取器中没有当前查询"} {"已经有一个与此Connection关联的打开DataReader,必须先关闭它."} {"会话已关闭!\ r \n对象名称:'ISession'."}

我已经添加了InRequestScope.我甚至添加了这个实现: NHibernate,奇怪的是"Session is Closed!" 错误

但是我仍在关闭塞申斯!错误.我甚至尝试创建一个新的Kernel.Get如果会话已关闭,但问题是即使会话打开时有时也会发生错误.请帮忙!我对这个问题很有见,我似乎无法在任何地方找到解决方案.我几乎认为NHibernate不可能同时处理多个会话.

UPDATE

也许有一种方法可以在打开新的之前等待已处理的会话?

堆栈跟踪

[ObjectDisposedException:会话已关闭!对象名:'ISession'.]
NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed()+ 192 NHibernate.Impl.AbstractSessionImpl.CheckAndUpdateSessionStatus()+55 NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)+171
NHibernate.Linq.DefaultQueryProvider.PrepareQuery (表达式表达式,IQuery&query,NhLinqExpression&nhQuery)+226
NHibernate.Linq.DefaultQueryProvider.Execute(表达式表达式)+80 NHibernate.Linq.DefaultQueryProvider.Execute(表达式表达式)+74 Remotion.Linq.QueryableBase 1.GetEnumerator() +193 System.Collections.Generic.List1..ctor(IEnumerable 1 collection) +432 System.Linq.Enumerable.ToList(IEnumerable1来源)+70
Gcus.PublicGeneralSite.Data.Core.Service.General.DetailsS​​ervice.FindItems(String item,String controller)在c:\ Users\wd\Desktop\master\Gcus.PublicGeneralSite.Data.Core\Service\General\DetailsS​​ervice.cs:724 Gcus.Com.Web.Controllers.CoursesController.Details(String category,String item)在c:\ Users\wd\Desktop\master\Gcus.Com.Web\Controllers\CoursesController.cs:213 lambda_method( Closure,ControllerBase,Object [])+366
System.We b.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller,Object [] parameters)+87
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary 2 parameters)+93 System.Web.Mvc.Async.ActionInvocation.InvokeSynchronousActionMethod() +97 System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult,ActionInvocation innerInvokeState)+53 System.Web.Mvc.Async.WrappedAsyncResult 1.End()+187 System.Web.Mvc.Async.AsyncResultWrapper.End( IAsyncResult asyncResult,Object tag)+136 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)+76 System.Web.Mvc.Async.AsyncInvocationWithFilters.b__3d()+ 164 System.Web.Mvc.Async.<> c__DisplayClass46.b__3f()+549 System.Web.Mvc.Async.<> c__DisplayClass33.b__32(IAsyncResult asyncResult)+75 System.Web.Mvc.Async.WrappedAsyncResult 1.End()+ 187 System.Web.Mvc.Async. AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+136 System.Web.Mvc.Async.Async ControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)+76 System.Web.Mvc.Async.<> c__DisplayClass2b.b__1c()+114 System.Web.Mvc.Async.<> c__DisplayClass21.b__1e(IAsyncResult asyncResult)+306 System.Web.Mvc .Async.WrappedAsyncResult 1.End()+ 176 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+72 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)+60 System. Web.Mvc.Controller.b__1d(IAsyncResult asyncResult,ExecuteCoreState innerState)+70 System.Web.Mvc.Async.WrappedAsyncVoid 1.End()+ 176 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag) +72 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+51 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)+66 System.Web.Mvc.Controller.b__15(IAsyncResult asyncResult,控制器控制器)+60 System.Web.Mvc.Async.WrappedAsyncVoid 1.End()+ 176 System.Web.Mvc.Async.Asyn cResultWrapper.End(IAsyncResult asyncResult,Object tag)+72 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+51 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)+60 System.Web .Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)+60 System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult,ProcessRequestState innerState)+70 System.Web.Mvc.Async.WrappedAsyncVoid 1 .End()+ 176 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+72 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+51 System.Web. Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)+60 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)+59 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+ 399 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&completedSynchronously)+1372 parameters) +603
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary


2.CallEndDelegate(IAsyncResult asyncResult) +137
System.Web.Mvc.Async.WrappedAsyncResultBase




1.CallEndDelegate(IAsyncResult asyncResult) +79
System.Web.Mvc.Async.WrappedAsyncResultBase




1.CallEndDelegate(IAsyncResult asyncResult) +75
System.Web.Mvc.Async.WrappedAsyncResultBase




1.CallEndDelegate(IAsyncResult asyncResult) +135
System.Web.Mvc.Async.WrappedAsyncResultBase




1.CallEndDelegate(IAsyncResult asyncResult) +98
System.Web.Mvc.Async.WrappedAsyncResultBase





1.CallEndDelegate(IAsyncResult asyncResult) +135
System.Web.Mvc.Async.WrappedAsyncResultBase




Neo*_*eto 2

我终于弄明白了。非常感谢@Oskar Berggren 至少热衷于理解我的困境。

问题是,事实上,我一直在共享一个会话。

这是我将开放会话绑定到 ContentService 的地方:

 Bind<IContentService>().To<ContentService>().InRequestScope();
        Bind<ISession>()
            .ToMethod(
                context =>
                    context.Kernel.Get<IMasterSessionSource>()
                        .ExposeConfiguration()
                        .BuildSessionFactory()
                        .OpenSession()
            )
            .WhenInjectedInto<IContentService>()
            .InRequestScope(); 
Run Code Online (Sandbox Code Playgroud)

这是我在 ContentService 中调用相同会话的地方

 public class ContentService : IContentService
    {
        private readonly ISession _session;

        public ContentService(ISession session)
        {
            _session = session;
        }

        public IQueryable<Question> Questions
        {
            get { return _session.Query<Question>(); }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这就是问题所在。我正在其他地方使用的另一个服务中调用相同的会话

public class DetailsService : IDetailsService
    {
        private readonly IContentService _contentService; //BAD


        public GeneralService(IContentService contentService)
        {
            _contentService = contentService; //BAD
        }
Run Code Online (Sandbox Code Playgroud)

这不是线程安全的,因为一个打开的会话正在被重用。每个服务都应该有自己的会话。

所以我为 DetailService 创建了它自己的会话的绑定,就像这样......

 Bind<IDetailsService>()
                .To<DetailsService>()
                .InRequestScope();

            Bind<ISession>()
                .ToMethod(
                    context =>
                    {
                        var lockObject = new object();

                        lock (lockObject)
                        {
                            return context.Kernel.Get<IMasterSessionSource>()
                                .ExposeConfiguration()
                                .BuildSessionFactory()
                                .OpenSession();
                        }
                    }
                )
                .WhenInjectedInto<IDetailsService>()
                .InRequestScope();
Run Code Online (Sandbox Code Playgroud)

我没有在该服务中调用 _contentService,而是将会话添加到其收缩器中

    private readonly ISession Session;

    public DetailsService(ISession session)
    {
        Session = session;
    }
Run Code Online (Sandbox Code Playgroud)

然后直接使用 Session.Query() 运行查询;

不再有会话关闭错误,不再有 DataReader 错误,终于有了一个工作产品。