Предыдущие значения должны быть в вашем объекте.
Допустим, у вас есть свойство ConcurrencyToken
:
public class MyObject
{
public Guid Id { get; set; }
// stuff
public byte[] ConcurrencyToken { get; set; }
}
Теперь вы можете установить ConcurrencyMode.Fixed
для этого свойства.Вам также необходимо настроить свою БД для ее автоматического обновления.
Когда вы запрашиваете БД, она будет иметь некоторое значение:
var mo = Context.MyObjects.First();
Assert.IsNotNull(mo.ConcurrencyToken);
Теперь вы можете отсоединить или сериализовать объект, но вынужно включить ConcurrencyToken
.Поэтому, если вы помещаете данные объекта в веб-форму, вам нужно сериализовать ConcurrencyToken
в строку и поместить ее в скрытый ввод.
Когда вы ApplyChanges
, вам необходимо включитьConcurrencyToken
:
Assert.IsNotNull(myObject.ConcurrencyToken);
using (var context = new MyContext())
{
context.MyObjects.ApplyChanges(myObject);
context.SaveChanges();
}
Наличие ConcurrencyMode.Fixed
изменяет UPDATE
SQL.Обычно это выглядит так:
UPDATE [dbo].[MyObject]
SET --stuff
WHERE [Id] = @0
С ConcurrencyMode.Fixed
это выглядит следующим образом:
UPDATE [dbo].[MyObject]
SET --stuff
WHERE [Id] = @0 AND [ConcurrencyToken] = @1
... поэтому, если кто-то обновил строку между временем чтения исходного токена параллелизмаи время, которое вы сохранили, UPDATE
повлияет на 0 строк вместо 1. В этом случае EF выдает ошибку параллелизма.
Поэтому , если что-либо из этого не работаетдля вас первым шагом является использование SQL Profiler для просмотра сгенерированного UPDATE
.