Почему NHibernate не отслеживает изменения, внесенные в мои объекты? - PullRequest
1 голос
/ 16 февраля 2012

Я использую Ninject, Fluent NHibernate и ASP.NET MVC.

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

Мой метод контроллера выглядит следующим образом

[HttpPost]
[UnitOfWork]
public ActionResult Method(int id)
{
    // Lookup entity, toggle a bool property on it and that is it
}

Мой атрибут UnitOfWork выглядит следующим образом

public class UnitOfWorkAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        NHibernateSession.Current.BeginTransaction();
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Exception == null && NHibernateSession.Current.Transaction.IsActive)
        {
            NHibernateSession.Current.Transaction.Commit();
        }
    }
}

Оба метода вызываются и ошибок не возникает, проблема в том, что когда вызывается NHibernateSession.Current (который просто возвращает NHibernate.ISession), ISession.IsDirty() ложно. NHibernate не думает, что что-то изменилось.

Раньше я без проблем использовал подобные настройки в других проектах, единственное отличие от этого в том, что я поменял StructureMap для Ninject, с которым я не очень знаком.

Соответствующие привязки:

Bind<IEntityRepository>().To<EntityRepository>().InRequestScope();
Bind<ISessionFactory>().ToMethod(x => NHibernateSession.CreateSessionFactory()).InSingletonScope();
Bind<ISession>().ToMethod(x => x.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();

Есть идеи, что я сделал не так? Я предполагаю, что это как-то связано с тем, что я испортил обработку сеанса, но я не уверен, что именно.

Редактировать: это то, что возвращает текущий вызов. Сеанс должен храниться так, чтобы каждый раз не нужно было создавать новый сеанс.

public static ISession Current
{
  get
  {
      var session = GetExistingSession();

      if (session != null)
        return session;

      session = _sessionFactory.OpenSession();
      HttpContext.Current.Items[SessionKey] = session;
      return session;
   }
 }

Ответы [ 2 ]

1 голос
/ 16 февраля 2012

Из вашего комментария на ваш вопрос я думаю, что каждый раз, когда вы звоните NHibernateSession.Current, вы получаете новую сессию.Это проблема.Ваша сессия должна иметь семантику времени жизни каждого веб-запроса.Вы захотите внедрить сеанс в свой контроллер или ваш фильтр.

1 голос
/ 16 февраля 2012

Вам нужно использовать ту же сессию IS для этого запроса, следовательно, InRequestScope().Вы можете изменить NHibernateSession.Current на что-то вроде return DependencyResolver.Current.GetService<ISession>();, но, вероятно, более предпочтительно, чтобы ctor вставлял ISession в FilterAttribute и сообщал об этом с помощью this.BindFilter<UnitOfWorkFilter>(FilterScope.Action, 0);

https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations

...