NHibernate не обновляет сущность, когда хранилище передается конструктором - PullRequest
0 голосов
/ 15 мая 2010

Я впервые работаю с NHibernate в сочетании с ASP.NET MVC и StructureMap. CodeCampServer служит отличным примером для меня. Мне действительно нравятся различные концепции, которые были реализованы там, и я могу многому научиться из этого.

В моих контроллерах я использую Constructur Dependency Injection, чтобы получить экземпляр нужного репозитория.

Моя проблема: : если я изменяю атрибут клиента, данные клиента не обновляются в базе данных, хотя Commit () вызывается для объекта транзакции (с помощью HttpModule).

public class AccountsController : Controller
{
    private readonly ICustomerRepository repository;

    public AccountsController(ICustomerRepository repository)
    {
        this.repository = repository;
    }

    public ActionResult Save(Customer customer)
    {
        Customer customerToUpdate = repository
            .GetById(customer.Id);

        customerToUpdate.GivenName = "test"; //<-- customer does not get updated in database
        return View();      
    }
}

С другой стороны это работает:

public class AccountsController : Controller
{
    [LoadCurrentCustomer]
    public ActionResult Save(Customer customer)
    {
        customer.GivenName = "test"; //<-- Customer gets updated
        return View();              
    }
}

public class LoadCurrentCustomer : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        const string parameterName = "Customer";

        if (filterContext.ActionParameters.ContainsKey(parameterName))
        {
            if (filterContext.HttpContext.User.Identity.IsAuthenticated)
            {                    
                Customer CurrentCustomer = DependencyResolverFactory
                    .GetDefault()
                    .Resolve<IUserSession>()
                    .GetCurrentUser();

                filterContext.ActionParameters[parameterName] = CurrentCustomer;
            }
        }

        base.OnActionExecuting(filterContext);
    }
}

public class UserSession : IUserSession
{
    private readonly ICustomerRepository repository;

    public UserSession(ICustomerRepository customerRepository)
    {
        repository = customerRepository;
    }

    public Customer GetCurrentUser()
    {
        var identity = HttpContext.Current.User.Identity;

        if (!identity.IsAuthenticated)
        {
            return null;
        }

        Customer customer = repository.GetByEmailAddress(identity.Name);
        return customer;
    }
}

Я также пытался вызвать update для хранилища, как показано в следующем коде. Но это приводит к NHibernateException, который говорит: «Незаконная попытка связать коллекцию с двумя открытыми сессиями». На самом деле есть только один.

public ActionResult Save(Customer customer)
{
    Customer customerToUpdate = repository
        .GetById(customer.Id);

    customer.GivenName = "test";
    repository.Update(customerToUpdate);

    return View();  
}

У кого-нибудь есть идея, почему клиент не обновляется в первом примере, а обновляется во втором примере? Почему NHibernate говорит, что есть две открытые сессии?

Ответы [ 2 ]

0 голосов
/ 16 мая 2010

Наконец я нашел проблему. Когда я получал клиента по его идентификатору, я всегда открывал новый сеанс вместо того, чтобы использовать сеанс в пределах области запроса.

Однако, большое спасибо за вашу помощь!

0 голосов
/ 15 мая 2010

попробуйте вызвать репозиторий. Flush ()

...