ASP.NET MVC +实体框架与并发检查 [英] ASP.NET MVC + Entity Framework with Concurrency check

查看:143
本文介绍了ASP.NET MVC +实体框架与并发检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现这个页面的样品之后一个应用程序:<一href=\"http://www.asp.net/entity-framework/tutorials/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application\">http://www.asp.net/entity-framework/tutorials/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application

I am trying to implement a application following the sample in this page: http://www.asp.net/entity-framework/tutorials/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application

我有一个域类时间戳并发检查现场:

I have a domain class with Timestamp as the concurrency check field:

public class PurchaseOrder {
    [Timestamp]
    public byte[] Timestamp {get; set;}
}

在我Edit.aspx我有时间戳作为隐藏字段(我用的是视图模型):

In my Edit.aspx I have the Timestamp as hidden field (I am using a view model):

<%: Html.HiddenFor(model => model.PurchaseOrder.Timestamp) %>

这是我的编辑()方法:

This is my Edit() method:

public ActionResult Edit(int id, FormCollection collection) {
     var purchaseOrder = db.PurchaseOrders.Find(id);
     UpdateModel(purchaseOrder, "PurchaseOrder", collection);

     db.Entry(purchaseOrder).State = EntityState.Modified;
     db.SaveChanges();
}

我在同一时间开了2个独立的浏览器相同的编辑页面(所以它们的时间戳是一样的),并更新他们一个接一个。

I opened the same edit page in 2 separate browser at the same time (so that their timestamp is the same), and update them one after the other.

当我更新的第二页,我期望的DbUpdateConcurrencyException。但是,我越来越没有。

When I update the second page, I expected a DbUpdateConcurrencyException. But I am getting none.

我认为发生的事情是,在第二页,我又在编辑操作得到purchaseOrder的对象从DB:

What I think happened is that in the second page, I am getting the purchaseOrder object again from the DB in the Edit action:

var purchaseOrder = db.PurchaseOrders.Find(id);

所以时间戳是因为previous编辑的新的时间戳。

So the timestamp is the new timestamp because of the previous edit.

但我预期的UpdateModel(),以取代从的FormCollection的时间戳值。
显然,这不是这种情况。

But I expected the UpdateModel() to replace the Timestamp value from the formcollection. Obviously, this is not the case.

如何能在我的隐藏字段检索purchaseOrder中的时间戳的值设置为,这样并发会被检测到?

How can I set the value of the Timestamp of the retrieved purchaseOrder to the in the hidden field, so that the concurrency will be detected?

推荐答案

<一个href=\"http://stackoverflow.com/questions/5327649/entity-framework-optimistic-concurrency-exception-not-occuring/5327770#5327770\">It不以这种方式工作。一旦你通过加载实体查找您不能直接更改它的时间戳。其原因是时间戳计算列。 EF包含每个加载实体内部原件和当前值。如果在加载的实体改变数值,只有当前值被改变和更新期间EF与当前值的原始值进行比较以了解哪些列必须被更新。但在计算列的情况下,EF不这样做,因为这样的话你的改变的值将不会被使用。

It doesn't work this way. Once you load entity by Find you cannot change its timestamp directly. The reason is that timestamp is computed column. EF holds internally original and current values for each loaded entity. If you change the value in the loaded entity, only current value is changed and during update EF compares the original value with the current value to know which columns must be updated. But in case of computed columns EF don't do that and because of that your changed value will never be used.

有两种解决方案。首先是没有从数据库加载实体:

There are two solutions. The first is not loading the entity from database:

public ActionResult Edit(int id, FormCollection collection) 
{
     // You must create purchase order without loading it, you can use model binder
     var purchaseOrder = CreatePurchaseOrder(id, collection);
     db.Entry(purchaseOrder).State = EntityState.Modified;
     db.SaveChanges();
}

第二个解决方案是在ObjectContext的API链接的问题描述小的黑客。如果你需要这个的DbContext API,你可以尝试这样的:

The second solution is small hack described in linked question for ObjectContext API. If you need this for DbContext API you can try something like:

public ActionResult Edit(int id, FormCollection collection) 
{
     var purchaseOrder = db.PurchaseOrders.Find(id);
     purchaseOrder.Timestamp = GetTimestamp(collection);
     // Overwrite original values with new timestamp
     context.Entry(purchaseOrder).OriginalValues.SetValues(purchaseOrder);
     UpdateModel(purchaseOrder, "PurchaseOrder", collection);
     db.SaveChanges();
}

这篇关于ASP.NET MVC +实体框架与并发检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆