使用nhibernate会话获取的结果的枚举错误创建sql查询

时间:2012-03-02 18:05:48

标签: nhibernate sharp-architecture

我正在使用sharp arch ver 1.0。

在NHibernate PostUpdateEvent中我试图访问数据库。

public class PostUpdateListener : IPostUpdateEventListener 
{ 
    public void OnPostUpdate(PostUpdateEvent postUpdateEvent) 
    { 
        var session = NHibernateSession.Current;

        var results = session.CreateSQLQuery("Select * from Storefront").List<object>();
        for (int i = 0; i < results.Count; i++)
        {
        }
  }

当我尝试保存任何实体并在postupdateevent中运行此选择查询时,它会在OnFlush上给出枚举错误。 NHibernate \ Listeners \ FlushFixEventListener .cs Line:35

我读到使用foreach循环运行枚举操作以便更好地运行for循环。但我尝试使用for循环。仍然没有区别。

使用SharArch NHibernate Transaction属性处理保存操作。如果我删除了Transaction属性,则postupdatelistener中的查询工作正常。

这是堆栈跟踪。

[InvalidOperationException:Collection已被修改;枚举操作可能无法执行。]    System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)+56    System.Collections.Generic.Enumerator.MoveNextRare()+58    System.Collections.Generic.Enumerator.MoveNext()+93    d:\ horn.horn \ orm \ nhibernate \ Working-2.1 \ src \ NHibernate \ Engine \ ActionQueue.cs中的NHibernate.Engine.ActionQueue.ExecuteActions(IList列表):112    d:\ horn.horn \ orm \ nhibernate \ Working-2.1 \ src \ NHibernate \ Engine \ ActionQueue.cs中的NHibernate.Engine.ActionQueue.ExecuteActions():147    d:\ horn.horn \ orm \ nhibernate \ Working-2.1 \ src \ NHibernate \ Event \ Default \ AbstractFlushingEventListener.cs中的NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource会话):241    d:\ horn.horn \ orm \ nhibernate \ Working-2.1 \ src \ NHibernate \ Event \ Default \ DefaultFlushEventListener.cs中的NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent事件):19    D:\ Solutions \ Infrastructure \ NHibernate \ Listeners \ FlushFixEventListener .cs:35中的Infrastructure.NHibernate.Listeners.FlushFixEventListener.OnFlush(FlushEvent事件)    在d:\ horn.horn \ orm \ nhibernate \ Working-2.1 \ src \ NHibernate \ Impl \ SessionImpl.cs:1478中的NHibernate.Impl.SessionImpl.Flush()    Infrastructure.NHibernate.LinqRepository 1.Save(T entity) in D:\Solutions\Infrastructure\NHibernate\LinqRepository.cs:95 Tasks.Shared.ContentEntityTasks 4.在D:\ Solutions \ Tasks \ Shared \ ContentEntityTasks.cs中保存(TSaveEntityRequestDetails详细信息):96    D:\ Solutions \ Web.Controllers \ Entity \ EntityController.cs中的Web.Controllers.Entity.EntityController.Edit(EntityViewModel entityViewModel,HttpPostedFileBase fileName,HttpPostedFileBase mainImageFileName,HttpPostedFileBase thumbnailFileName):379    lambda_method(ExecutionScope,ControllerBase,Object [])+185    System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary 2 parameters) +236 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary 2个参数)+31    System.Web.Mvc。&lt;&gt; c_ DisplayClassa.b _7()+85    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter,ActionExecutingContext preContext,Func 1 continuation) +235491 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func 1 continuation)+235491    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter,ActionExecutingContext preContext,Func 1 continuation) +235491 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func 1 continuation)+235491    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext,IList 1 filters, ActionDescriptor actionDescriptor, IDictionary 2个参数)+288    System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext,String actionName)+235670    System.Web.Mvc.Controller.ExecuteCore()+ 174    System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)+209    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+599    System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+171

1 个答案:

答案 0 :(得分:0)

似乎正在发生的事情是会话因为CreateSQLQuery调用而决定刷新。这会导致将更新后事件添加到需要触发的内部事件列表中(猜测此事件)。

您应该能够通过使用该事件来访问子会话而不是主NH会话来修复它。像这样:

public class PostUpdateListener : IPostUpdateEventListener 
{ 
    public void OnPostUpdate(PostUpdateEvent postUpdateEvent) 
    { 
        var session = postUpdateEvent.Session.GetSession(EntityMode.Poco)

        var results = session.CreateSQLQuery("Select * from Storefront").List<object>();
        for (int i = 0; i < results.Count; i++)
        {
        }
    }
}

如果您还需要在此事件中添加或更新实体,例如,出于审核日志的目的,您还需要确保刷新内部会话。