简体   繁体   English

无法使用启用并发修复的实体框架更新 object

[英]Cannot update an object using Entity Framework with Concurrency Fixed enabled

I will be more specific here.. This is a strange problem and really, i am not understanding why this is happening..我将在这里更具体.. 这是一个奇怪的问题,真的,我不明白为什么会这样..

In my data model every table has a column of type rowversion, and in my EDM (Entity Data Model) i enabled version to be my rowversion and maps exacly with my column rowversion in database.在我的数据 model 中,每个表都有一个 rowversion 类型的列,并且在我的 EDM(实体数据模型)中,我启用了版本作为我的 rowversion,并与我在数据库中的 rowversion 列精确映射。

Here is the problem.这就是问题所在。

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!

I go to profiler and i see that the query that is build contains the Newer version and not the older (not that i affected from the post form to the object that come from the database).我 go 到探查器,我看到构建的查询包含较新版本而不是较旧版本(不是我从来自数据库的 object 的帖子表单影响)。

For me appears that EF when is building is using the newVersion in some place, and not uses the current value that controls concurrency in the object..对我来说,EF 在构建时似乎在某个地方使用了 newVersion,而不是使用控制 object 中的并发的当前值。

Somebody know what it is happening????有人知道这是怎么回事吗???

The EF tracks two values for every property: The value originally read from the DB, and the new value you assign. EF 跟踪每个属性的两个值:最初从 DB 读取的值,以及您分配的新值。

For the concurrency token / row version, it always uses the original value in the WHERE when doing the update.对于并发令牌/行版本,它在进行更新时始终使用 WHERE 中的原始值。 This does make sense if you think about it, but it doesn't work for your situation.如果您考虑一下,这确实是有道理的,但它不适用于您的情况。

In your Step 7, you get the new value of the timestamp, created during the update in step 4. So that's what appears in the WHERE clause.在您的第 7 步中,您将获得在第 4 步更新期间创建的时间戳的值。这就是WHERE子句中出现的内容。 Updating the property of the entity doesn't fix this, because that changes the "current" value of the property, not the "originally read" value.更新实体的属性并不能解决此问题,因为这会更改属性的“当前”值,而不是“原始读取”值。

Here's a workaround:这是一个解决方法:

// 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();

Here is my workaround.. for persistance ignorant:这是我的解决方法..对于持久性无知:

       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);
        }

The essence is..本质是..

POCO don't notify the context for changes, so when i update an entity, the entry still remains unchanged. 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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM