Как использовать проверку параллелизма с EF 4.0 POCO Self Tracking Entities в сценарии N-уровня? - PullRequest
1 голос
/ 05 марта 2010

Я использую VS1010RC с шаблонами P4O для самоконтроля T4.

В моем методе службы обновлений WCF я использую что-то похожее на следующее:

using (var context = new MyContext())
{
  context.MyObjects.ApplyChanges(myObject);
  context.SaveChanges();
}

Это работает нормально, пока я не установлю ConcurrencyMode = Fixed для сущности, а затем получу исключение. Похоже, что контекст не знает о предыдущих значениях, поскольку оператор SQL использует значение измененных сущностей в предложении WHERE.

Какой правильный подход при использовании ConcurrencyMode = Fixed?

Ответы [ 2 ]

2 голосов
/ 05 марта 2010

Предыдущие значения должны быть в вашем объекте.

Допустим, у вас есть свойство 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.

0 голосов
/ 07 мая 2010

Марк,

Объекты, созданные как «объекты самообследования», нельзя считать чистыми POCO;

Вот причина: STE работают хорошо, только если ваш клиент использует сгенерированные прокси из шаблона STE T4. Отслеживание изменений и, следовательно, ваша служба будут работать только с этими сгенерированными прокси.

В чистом мире POCO (совместимость, Не все клиенты .Net 4.0, ..) вы не можете поставить ограничения на вашего клиента. Например, Facebook не будет писать сервис, который может обрабатывать только клиенты .Net 4.0.

STE могут быть хорошим выбором в некоторых средах, все зависит от ваших требований.

...