Невозможно обновить объект, используя Entity Framework с включенным фиксированным параллелизмом - PullRequest
1 голос
/ 08 июня 2011

Я буду более конкретным здесь .. Это странная проблема, и на самом деле, я не понимаю, почему это происходит ..

В моей модели данных каждая таблица имеет столбец типа rowversion, и вмой EDM (Entity Data Model), я включил версию, чтобы быть моей строкой и точно соответствует моей версии строки моего столбца в базе данных.

Вот проблема.

1) I List items
2) I go update one item, (supose with id 4)
3) I send to the form in a hiddenfield the value of the rowversion
4) Someone updated in database some field in id 4 (making the rowversion to change)
5) I update the new values
6) i Convert string data with rowversion to byte[]
7) I get the object with primary key from the database and affect all properties of the object returned from database with model binded object that come from the form post including the rowversion!
8) I invoke SaveChanges()
9) The Problem!

Я иду в профилировщик и яобратите внимание, что запрос, который является сборкой, содержит более новую версию, а не более старую (не то, что я затронул форму публикации для объекта, поступающего из базы данных).

Мне кажется, что EF при сборке используетnewVersion в каком-то месте и не использует текущее значение, управляющее параллелизмом в объекте ..

Кто-то знает, что это происходит ????

Ответы [ 2 ]

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

Вот мой обходной путь .. для невежественности:

       public void Update<TEntity>(TEntity Entity) where TEntity : class {
            ObjectStateEntry entry = _Context.ObjectStateManager.GetObjectStateEntry(Entity);
            entry.ChangeState(EntityState.Modified);
            entry.AcceptChanges();
            entry.ChangeState(EntityState.Modified);
        }

Суть ..

POCO не уведомляет контекст об изменениях, поэтому, когда я обновляю сущность, запись все равно остается неизменной.

1) I get the entry with Entity passed in the method
2) I change the state to Modified
3) I call AcceptChanges.. (note that in step 2 i changed the state to modified, so AcceptChanges now copies the CurrentValues to OriginalValues.. - Looks that implementation of AcceptChanges just procede if the state are different than Unchanged and makes sence)
4) I got the values copied but the default behavior of acceptChanges is let the state Unchanged..
5) I change the state to modified, so the SaveChanges can build the Update Command.
0 голосов
/ 08 июня 2011

EF отслеживает два значения для каждого свойства: значение, первоначально прочитанное из БД, и новое назначенное вами значение.

Для версии токена / строки параллелизма всегда используется оригинал значение в ГДЕ при выполнении обновления.Это имеет смысл, если вы думаете об этом, но это не работает для вашей ситуации.

На вашем шаге 7 вы получите новое значение временной метки, созданное во время обновленияна шаге 4. Так вот что появляется в предложении WHERE.Обновление свойства объекта не исправляет это, потому что это изменяет «текущее» значение свойства, а не «первоначально прочитанное» значение.

Вот обходной путь:

// get updated object from DB, with "newer" concurrency token/timestamp
var myFoo = myContext.Foos.Single(f => f.Id == id);
// assign the "current" value of ConcurrencyToken
myFoo.ConcurrencyToken = concurrencyToken; 
// now copy the "current" value you just assigned to the "originally read from DB" 
// value, overwriting the ConcurrencyToken value you read from DB
var ose = Context.ObjectStateManager.GetObjectStateEntry(myFoo);
ose.AcceptChanges(); 
// assign rest of properties
myFoo.SomeOtherProperty = someOtherValue;
Context.SaveChanges();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...