У меня есть служба WCF, которая выполняет вызовы в мои классы Entity Framework Repository для доступа к данным. Я использую Entity Framework 4 CTP и использую мои собственные объекты POCO, а не объекты автоматически генерируемых объектов.
Время жизни контекста ограничено вызовом метода. Для методов Select / Insert и Update я создаю контекст и располагаю его тем же методом, возвращая отсоединенные объекты сущностей.
Сейчас я пытаюсь найти наилучший способ решения проблем параллелизма. Например, так выглядит мой метод обновления
public static Sale Update(Sale sale)
{
using (var ctx = new DBContext())
{
var SaleToUpdate =
(from t in ctx.Sales where t.ID == sale.ID select t).FirstOrDefault();
if (SaleToUpdate == null) throw new EntityNotFoundException();
ctx.Sales.ApplyCurrentValues(sale);
ctx.SaveChanges();
return sale;
}
}
Это работает нормально, но, поскольку я работаю в автономном режиме, не возникает исключений, если запись была изменена с момента ее получения. Это может вызвать проблемы с параллелизмом.
Каков наилучший способ решить эту проблему, если вы используете платформу сущностей поверх WCF и не сохраняете глобальный контекст?
Единственный метод, который я могу придумать, - это присвоить моим объектам номер версии и увеличивать его при каждом вызове сохранения. Это позволило бы мне проверить, что версия не изменилась перед сохранением. Не самое удачное решение, которое я знаю, и которое все же позволит клиенту менять номер версии, чего я действительно не хочу, чтобы он мог сделать.
РЕДАКТИРОВАТЬ:
Используя предложение Ладислава Мрнки о полях RowVersion в моих сущностях, каждая из моих сущностей теперь имеет поле с именем Версия типа RowVersion. Затем я изменил свой метод обновления, чтобы он выглядел следующим образом.
public static Sale Update(Sale sale)
{
using (var ctx = new DBContext())
{
var SaleToUpdate =
(from t in ctx.Sales where t.ID == sale.ID select t).FirstOrDefault();
if (SaleToUpdate == null) throw new EntityNotFoundException();
if (!sale.Version.SequenceEqual(SaleToUpdate .Version))
throw new OptimisticConcurrencyException("Record is out of date");
ctx.Sales.ApplyCurrentValues(sale);
ctx.SaveChanges();
return sale;
}
}
Кажется, это работает, но если я должен делать это по-другому, пожалуйста, дайте мне знать. Я попытался использовать встроенные средства управления параллелизмом Entity Frameworks, установив фиксированный режим параллелизма полей версии, но, к сожалению, это не сработало, поскольку, когда я выполнял запрос, чтобы получить неизмененный SaleToUpdate, он брал свою версию и использовал ее для проверки параллельности. что, очевидно, актуально. Такое ощущение, что в фреймворке сущностей здесь чего-то не хватает.