в моем приложении ASP.NET MVC я отделил модель предметной области от модели представления.
Я преобразовываю свою сущность в объект модели представления, чтобы я мог "кормить" свои представления только необходимыми данными (для этой цели я использовал valueinjecter ).
Во время процесса сохранения мой контроллер возвращает объект модели представления, преобразует его в объект модели предметной области и пытается сохранить его с помощью SaveOrUpdate. Я заметил, что если я пытаюсь обновить существующую запись, Nhibernate рассматривает ее как новый объект и принудительно выполняет INSERT, даже если у моего объекта правильный идентификатор.
Я не загрузил (получить/загрузить) объект Прежде чем я хотел бы избежать повторного сопоставления всех полей.
Есть ли что-то, что я делаю неправильно? Каков наилучший способ добиться этого?
***** - ОБНОВИТЬ - ***
Мой контроллер получает пользователя (ViewModel), проверяет его и пытается сохранить через сервисный уровень как сущность:
public ActionResult Edit(Guid id, Models.User User)
{
...
var user = new Domain.User();
user.InjectFrom(User);
user.SetId(id);
user = this._SecurityService.SaveUser(user);
}
Это сервис:
public Domain.User SaveUser(Domain.User User)
{
bool Result = false;
if (this._ValidationEngine.IsValid(User))
{
using (_UnitOfWork)
{
if (User.Code != Guid.Empty)
{
var user = this._UserRepository.Load(User.Code);
user.InjectFrom(User);
User = this._UserRepository.Update(user);
}
else {
User = this._UserRepository.Save(User);
}
Result = _UnitOfWork.Commit();
}
}
return (User);
}
Меня беспокоит тот факт, что мне приходится так много раз преобразовывать свою модель представления/сущность. Теперь, когда я пытаюсь сохранить нового пользователя, я получаю следующее сообщение: Строка была обновлена или удалена другой транзакцией (или сопоставление несохраненных значений было неправильным)
Вероятно, это каким-то образом связано с тем, что Дарин говорил мне.
Есть ли лучшие способы сделать то, что я пытаюсь сделать?
ОБНОВЛЕНИЕ
Я заметил, что ошибка "Строка была обновлена или удалена..." вызвана тем, что у меня есть версия, определенная для моих сопоставлений. Насколько я понимаю, мне нужно, чтобы Id и версия соответствовали объекту, который я хочу обновить.
Я хотел бы понять, как другие люди делают эти вещи. с DDD + ASP.NET MVC + NHibernate???
РЕШЕНИЕ
Все мои объекты имеют определенную версию (забыл сказать, извините):
<version name="Version" type="System.Int32" unsaved-value="0">
<column name="Version" not-null="true" />
</version>
Как объяснил Айенде здесь, Nhibernate пытается обновить моя сущность с таким запросом:
UPDATE Table SET field1 = 'bla', Version = (y+1) WHERE id = x AND Version = y
где y должна быть версией моей сущности. Поскольку я не заполнил свой объект версией, это сгенерировало бы исключение StaleObjectException.
Я добавил поле версии в свою модель представления. Я сохраняю его в скрытом поле моего представления вместе с идентификатором.
Теперь мой контроллер получает модель представления с идентификатором и версией. Я ввожу эти поля в свой объект домена и позволяю репозиторию сохранить его (я не перезагружаю свой объект):
User = this._UserRepository.Update(user);
Если я получаю исключение StaleObjectException, это означает, что кто-то другой обновил строку БД, и я предоставлю пользователю некоторую обратную связь.