Я впервые работаю с 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 говорит, что есть две открытые сессии?