EF4 - обновить [Table] set @p = 0 где - PullRequest
5 голосов
/ 04 июня 2011

Проходя через профилировщик SQL, я заметил следующий запрос, сгенерированный EF4.

exec sp_executesql N'declare @p int
update [dbo].[User]
set @p = 0
where (([UserID] = @0) and ([RowVersion] = @1))
select [RowVersion]
from [dbo].[User]
where @@ROWCOUNT > 0 and [UserID] = @0',N'@0 int,@1 binary(8)',@0=1,@1=0x000000000042DDCD

Я не уверен, почему EF4 генерирует это, хотя я на самом деле не обновляю никакие столбцы таблицы User в этом UnitOfWork. Выполнение этого запроса обновляет столбец RowVersion (тип данных отметки времени) , что приводит к исключению OptimisticConcurrencyException в следующем UnitOfWork.

Быстрый поиск в Google привел меня к этой ссылке , которая подтверждает, что другие тоже сталкивались с этим сценарием, пока не нашли решения.

Буду очень признателен за любые указатели.

Редактировать: Пример кода для репликации проблемы.

enter image description here

Таблицы пользователей и сеансов имеют отношение внешний ключ . Кроме того, в EF4 я установил «Режим параллелизма» для столбцов RowVersion обоих объектов на Исправлено .

Ниже приведен пример метода для репликации сценария.

 private static void UpdateSession()
    {
        using (var context = new TestEntities())
        {
            context.ContextOptions.ProxyCreationEnabled = false;

            var session = context.Users.Include("Sessions").First().Sessions.First();
            session.LastActivityTime = DateTime.Now;

            context.ApplyCurrentValues("Sessions", session);

            context.SaveChanges();
        }
    }

Я вижу из Sql profiler следующие запросы, генерируемые EF4.

exec sp_executesql N'update [dbo].[Session]
set [LastActivityTime] = @0
where (([SessionID] = @1) and ([RowVersion] = @2))
select [RowVersion]
from [dbo].[Session]
where @@ROWCOUNT > 0 and [SessionID] = @1',N'@0 datetime2(7),@1 int,@2 binary(8)',@0='2011-06-20 09:43:30.6919628',@1=1,@2=0x00000000000007D7

А следующий запрос странный.

    exec sp_executesql N'declare @p int
update [dbo].[User]
set @p = 0
where (([UserID] = @0) and ([RowVersion] = @1))
select [RowVersion]
from [dbo].[User]
where @@ROWCOUNT > 0 and [UserID] = @0',N'@0 int,@1 binary(8)',@0=1,@1=0x00000000000007D3

Ответы [ 3 ]

4 голосов
/ 15 июля 2011

Не уверен, если это все еще проблема для вас, но вот исправление от MS http://support.microsoft.com/kb/2390624

3 голосов
/ 27 июля 2012

Нашел ссылку на другой форум и получил возможность загрузить исправление, упомянутое Крисом Ивановым.

http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=2390624

0 голосов
/ 04 июня 2011

Не уверен насчет EF4, но в версии 4.1 мы отключили версию строки / метку времени, задав для нее значение concurrenttoken = false.

Мы сделали это, потому что

  1. Это было вычисленное поле в нашей базе данных
  2. Оно никогда не должно изменяться приложением (в нашем случае)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...