Я использую поле Version для управления параллелизмом в приложении ASP.NET MVC 4.Проблемы с оптимистичным параллелизмом NHibernate в сценарии веб-приложения
Mapping:
<class name="User" table="Users">
<id name="Id">
<generator class="native"/>
</id>
<version name="Version" column="Version"/>
... other fields omitted for brevity...
Entity:
public class User
{
public virtual int Id { get; set; }
public virtual int Version { get; set; }
... other fields omitted for brevity...
Я использую следующий подход:
- чтения примитив Id и карту на мой UserDto лица (Dto для данных перенос объекта), в том числе поле версии
- показать форма для редактирования UserDto сущность
- получать публикуемую UserDto сущность
Тогда я следующее:
// read the original entity from the database using my repository wrapper around NHibernate
var rep = RepositoryFactory.Create<User>(currentUnitOfWork);
User originalEntity = rep.GetById(userDto.Id);
// optimistic lock control - keep the version as the user saw it
originalEntity.Version = userDto.Version;
... other fields omitted for brevity...
rep.Update(originalEntity);
Проблема заключается в том, что даже если userDto.Version не соответствует originalEntity.Version , NHibernate игнорирует мою userDto.Version и использует initialEntity.Version (очевидно, из кеша первого уровня, поскольку объект был просто прочитан). Такое поведение делает поле моей версии совершенно бесполезным.
Как заставить NHibernate использовать предоставленное мной значение Version, а не кешированное?
Кроме того, было бы здорово как-то сделать контроль версий более прозрачным для других программистов, которые используют мой репозиторий, но в настоящее время у меня нет идей, как заставить его автоматически получать версию из полученного объекта и заставлять NHibernate использовать его без программирования, даже замечая его.
Любые идеи?
У вас есть файл настроек, правильно настроенный? он должен генерировать инструкцию обновления, например 'UPDATE People SET ... WHERE PersonID = @ p0 AND Version = @ p1', где' @ p1' = версия, как прочитанная пользователем изначально. см. статью [Ayendes post on NHibernate Concurrency] (http://ayende.com/blog/3946/nhibernate-mapping-concurrency) –
Да, это сгенерирует это, но значение Версии является тем, которое оно только что прочитало из базы данных и а не тот, который я установил вручную в originalEntity.Version = userDto.Version. Кажется, NHibernate просто игнорирует мое обновление вручную в поле «Версия». Если я сломаю строку «Обновление» и изменим версию в базе данных, я получу ObjectStaleStateException, как и ожидалось. – JustAMartin