Ошибка перечисления результатов, полученных с помощью сеанса nhibernate, создать запрос sql

Я использую острую арку версии 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 Строка: 35

Я прочитал, что использование цикла foreach запускает операцию перечисления, поэтому лучше запустить цикл. Но я попробовал с циклом. все равно не имеет значения.

Операция сохранения обрабатывается атрибутом транзакции SharArch NHibernate. Если я удаляю атрибут Transaction, запрос в postupdatelistener работает нормально.

вот трассировка стека.

[InvalidOperationException: коллекция была изменена; операция перечисления может не выполняться.] System.ThrowHelper.ThrowInvalidOperationException(ресурс ExceptionResource) +56 System.Collections.Generic.Enumerator.MoveNextRare() +58 System.Collections.Generic.Enumerator.MoveNext() +93 NHibernate.ue.Eng. ExecuteActions(список IList) в d:\horn.horn\orm\nhibernate\Working-2.1\src\NHibernate\Engine\ActionQueue.cs:112 NHibernate.Engine.ActionQueue.ExecuteActions() в d:\horn.horn\orm\nhibernate\Working-2.1\src\NHibernate\Engine\ActionQueue.cs:147 NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(сеанс IEventSource) в каталоге d:\horn.horn\orm\nhibernate\Working-2.1\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:241 NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(событие FlushEvent) в d:\horn.horn\orm\nhibernate\Working-2.1\src\NHibernate\Event\Default\DefaultFlushEventListener.Exvent \ Default:19 Infrastructure.NHibernate.Listeners.FlushFixEventListener.OnFlush(событие FlushEvent) в D:\Solutions\Infrastructure\NHibernate\Listeners\FlushFixEventListener .cs:35 NHibernate.Impl.SessionImpl.Flush() в d:\horn.horn\orm\nhibernate\Working-2.1\src\NHibernate\Impl\SessionImpl.cs:1478 Инфраструктура.NHibernate.LinqRepository1.Save(T entity) in D:\Solutions\Infrastructure\NHibernate\LinqRepository.cs:95 Tasks.Shared.ContentEntityTasks4.Сохранить (подробности TSaveEntityRequestDetails) в D:\Solutions\Tasks\Shared\ContentEntityTasks.cs:96 Web.Controllers.Entity.EntityController.Edit(EntityViewModel entityViewModel, HttpPostedFileBase fileName \ fileNameFileFileNameFileFileFileFileNameFileFile_FileNameFile_FileNameFile_FileNameFile_FileNameFileNameFileNameFileNameFileNameFileNameFileNameFileNameFileNameFileNameFileNameFileNameFileNameFileNameFileNameFileBestFileNameFileNameFileBestFileName) Web.Controllers\Entity\EntityController.cs: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, IDictionary2 параметра) +31 System.Web.Mvc.<> C_ DisplayClassa.b_7 () +85 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (фильтр IActionFilter, предварительный текст ActionExecutingContext, Func1 continuation) +235491 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 продолжение) +235491 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(фильтр IActionFilter, ActionExecutingContext preContext, Func1 continuation) +235491 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 продолжение) +235491 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary2 параметра) +288 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +235670 System.Web.Mvc.Controller.ExecuteCore() +174 System.Web.Mvc.MvcHandler.ProcessRequteBextHtext () 209 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +599 System.Web.HttpApplication.ExecuteStep(шаг IExecutionStep, логический и завершенный синхронно) +171

1 ответ

Похоже, что происходит, когда сессия решает сбросить из-за вызова 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++)
        {
        }
    }
}

Если вам также требуется добавить или обновить сущности внутри этого события, например, для целей журнала аудита, вам также следует убедиться, что вы очищаете внутренний сеанс.

Другие вопросы по тегам