У меня проблема с привязкой модели в моем приложении ASP.NET MVC 2 RC, которое использует NHibernate для доступа к данным. Мы пытаемся создать приложение с использованием Ruby on Rails и иметь очень простую архитектуру, в которой сущности домена используются на всем пути от базы данных до представления.
Приложение имеет несколько доменных сущностей, которые могут быть проиллюстрированы следующими двумя классами:
public class Product {
...
public Category Category { get; set; }
}
public class Category {
public int Id { get; set; }
public string Name { get; set; }
}
В представлении, которое отображает форму редактирования, есть следующий оператор для отображения раскрывающегося списка:
<%= Html.DropDownListFor(model => model.Category.Id,
new SelectList(ViewData["categories"] as IList<Category>, "Id", "Name"),
"-- Select Category --" ) %>
Пожалуйста, не обращайте внимания на использование «нетипизированных» данных представления для хранения коллекции категорий.
Метод действия, который получает сообщение формы, аналогичен следующему. Обратите внимание, что атрибут TransactionFilter добавляет обработку транзакции NHibernate и фиксирует транзакцию, если не возникает исключений и проверка завершается успешно.
[HttpPost]
[TransactionFilter]
public ActionResult Edit(int id, FormCollection collection) {
var product = _repository.Load(id);
// Update the product except the Id
UpdateModel(product, null, null, new[] {"Id"}, collection);
if (ModelState.IsValid) {
return RedirectToAction("Details", new {id});
}
return View(product);
}
Моя проблема заключается в том, что для product.Category.Id задано значение, выбранное в форме, например, Category.Id = "2". Использование связующего устройства модели по умолчанию приводит к следующему типу исключения NHibernate:
identifier of an instance of Name.Space.Entities.Category was altered from 4 to 2
Это имеет большой смысл, поскольку продукту уже назначена категория, и изменяется только первичный ключ этой существующей категории. Вместо этого должен был быть назначен другой экземпляр категории.
Я полагаю, что для решения этой проблемы можно создать собственный ModelBinder, но есть ли более простой способ заставить это работать? Могут ли (и должны ли) доменные сущности быть изменены, чтобы справиться с этим?