NHibernate + ASP.NET MVC: сеанс подшивки моделей закрыт - PullRequest
1 голос
/ 22 сентября 2009

Я использую привязку пользовательской модели для привязки Order / OrderItem в своих действиях. Эта модель связывания использует ServiceLocator.Current.GetInstance (); где ICart, в свою очередь, зависит от IOrderRepository (не уверен, имеет ли это значение).

Теперь все работает нормально, когда я создаю элемент первого заказа. И когда я создаю второй. Затем я пытаюсь отобразить заказ, который теперь содержит два элемента заказа. Это делается с помощью

  public ActionResult Show(Order order) {}

, где порядок связан с моим пользовательским переплетом. Я отслеживаю его BindModel и вижу, что после вызова

  order = cart.GetOrder(id);

элементы заказа в порядке - то есть я добавляю окно «Просмотр», просматриваю свойства, продукты, и все они в порядке.

Однако, когда поток управления переходит к методу действия Показать (заказ), первый элемент заказа имеет недопустимые продукты - при доступе к ним возникает следующая ошибка (известная):

NHibernate.LazyInitializationException: инициализация [Orders.Core.OrderItem # 5440c233-fb7e-4dc9-8aec-9c8c0115808b] - не удалось лениво инициализировать коллекцию ролей: Orders.Core.OrderItem.Products, ни один сеанс или сессия не были закрыты

Теперь я вижу это в окне Watch при просмотре заказа. Элементы [0] .Products.

Странно то, что второй пункт заказа все еще в порядке! Так что, если он пойдет как

  • HTTP-запрос ... Моя модель Binder - получить заказ с помощью orderRepository.Get (id) - сессия в порядке для обоих элементов заказа ...
  • MVC делает свое волшебство
  • метод действия Show (Order order) <- здесь сеанс для order.Items [0]. Продукты потеряны, а для Items [1] нет </li>

Если я добавлю еще один элемент к заказу, то в Show () будет отображаться только элемент [2]. Продукты верны, оба элемента [0] и элемент [1] плохие (без сеанса).

Что здесь происходит?

Я использую Sharp Architecture и Session для каждого запроса. Я на самом деле убедился, что EndRequest не вызывается между механизмом связывания модели, получающим свой заказ, и Show (), получающим неправильный.

ОБНОВЛЕНИЕ: некоторый код (важные строки)

public class Cart : ICart
{
      public Cart(IOrderRepository orderRepository, ICurrentUser currentUser, IUserSessionStorage storage) {}
      public Order GetOrder(Guid id)
      {
         return orderRepository.Get(id);
      }
}

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
  var cart = ServiceLocator.Current.GetInstance<ICart>();
  //Guid guidId = new Guid(id_value_from_context);
  var order = cart.GetOrder(guidId); // here order is OK completely
  return order;
}

OrderRepository является репозиторием S # arp Architecture и использует класс WebSessionStorage, который закрывает Session только в обработчике EndRequest. Как я уже сказал, я подтвердил, что НЕ вызывается между заказом в порядке и заказом нет.

Обновление: Интересно, может ли это быть из-за дополнительной ручной транзакции вокруг orderRepository.Save (order). Завтра займусь расследованием, но нашел здесь что-то похожее на SO.

ОБНОВЛЕНИЕ: Более того, это происходит только после этого:

cart.Save(item);
return RedirectToAction<OrdersController>(c => c.Show(item.Order));

Когда я иду в адресную строку и нажимаю «Enter», чтобы перезагрузить страницу, она работает правильно. Так что это разовая проблема.

Что смешно, если я это сделаю, такой ошибки не будет:

return RedirectToAction("Show", "Orders", new { order = item.Order });

Так что MvcContrib пытается обработать порядок в TempData, я бы сказал ...

Я обнаружил, что у меня это на контроллерах:

   [PassParametersDuringRedirect]
   public class OrdersController

и подумал, что мой параметр заказа прибывает из TempData вместо ModelBinder ... хотя связыватель модели тоже срабатывал. Но когда я удалил атрибут, проблемы не исчезли. Так что это что-то с RedirectToController <> от MvcContrib, но я понятия не имею, почему это происходит.

Ответы [ 2 ]

0 голосов
/ 23 сентября 2009

Боже мой, я установил [PassParametersDuringRedirect] на свой BaseController. Я действительно сделал это в то время, когда я экспериментировал с MvcContrib, и просто забыл об этом. И он вернулся и укусил меня так сильно, что я потерял несколько часов, пытаясь решить эту проблему.

Итак, проблема в том, что я глуп, и извлеченный урок заключается в том, что никогда нельзя использовать общесистемные атрибуты / поведение, поскольку это не лучше, чем глобальные переменные в смысле побочных эффектов.

0 голосов
/ 22 сентября 2009

NHibernate.LazyInitializationException: инициализация [Orders.Core.OrderItem # 5440c233-fb7e-4dc9-8aec-9c8c0115808b] - не удалось лениво инициализировать коллекцию ролей: Orders.Core.OrderItem.Products, ни один сеанс или сеанс не был закрыт

означает, что ваша сессия была закрыта до того, как вы запросили товар. Вы уверены, что ничто не закрывает вашу сессию? может быть, вы можете опубликовать код?

...