Я пытаюсь реализовать Оптимистическую блокировку в приложении asp.net MVC, а также предоставить контрольный журнал.
Инфраструктура аудита основана на возможности вызова DataContext.GetModifiedMembers во время SubmitChanges, что, я думаю, имеет смысл.
Оптимистическая блокировка использует временные метки ROWVERSION, сериализованные в base64 и помещенные в скрытое поле в представлении.
Мое действие редактирования выглядит так:
[AcceptVerb(HttpVerb.Post)]
public ActionResult Edit(MyType myType)
{
context.MyTypes.Attach(myType, true);
context.SubmitChanges(ConflictMode.FailOnFirstConflict);
}
При этом DataContext.GetModifiedMembers всегда будет возвращать ВСЕ свойства MyType, а не только те, которые изменены между базой данных и предоставленными значениями, что нарушает аудит.
В частности, он возвращает каждое свойство, которое было изменено со своего нового значения на новое, поэтому я даже не могу сделать что-нибудь более умное со списком.
Я сначала попытался загрузить объект, прежде чем прикрепить его, но это дает исключение для дубликата ключа.
Затем я попытался использовать UpdateModel, т.е.
[AcceptVerb(HttpVerb.Post)]
public ActionResult Edit(int id, FormCollection col)
{
var mt = context.MyTypes.Single( mt => mt.id = id);
UpdateModel(mt);
context.SubmitChanges(ConflictMode.FailOnFirstConflict);
}
Это работает с аудитом, но не дает оптимистической блокировки.
Вместо ChangeConflictException я получаю InvalidOperationException, потому что UpdateModel изменяет поле concurrentTS (которое, очевидно, доступно только для чтения).
Что я делаю не так?