尽管有冲突的更新,但EF没有抛出DbUpdateConcurrencyException [英] EF not throwing DbUpdateConcurrencyException despite conflicting updates

查看:92
本文介绍了尽管有冲突的更新,但EF没有抛出DbUpdateConcurrencyException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在具有Web客户端的Web API服务器上使用EF 6.x(代码优先),我需要实现并发处理。问题是我什至无法获得EF来生成异常。

I am using EF 6.x (code-first) on a Web API server with web clients and I need to implement concurrency handling. The problem is that I cannot even get EF to generate an exception.

我发现的大多数示例似乎都没有使用分离的实体,即DTO发送到Web客户端,然后在其中进行更新,然后将其保存回

Most examples that I have found seems to not be using "detached entities", where the DTO is sent to a web client where it is updated and then saved back to the server at a later time (which is my scenario).

假设我有公司记录:

public class Company 
{
    int CompanyId { get; set; }
    string CompanyName { get; set; }

    [Timestamp]
    public byte[] RowVersion { get; set; }
}

1)用户A使用ID为的公司 = 0, RowVersion 是0x0000000000002B0A

1) User A pulls up company with Id = 0, RowVersion is 0x0000000000002B0A

2)我运行 UPDATE Company SET CompanyName ='Acme Changed,Inc.',其中CompanyId = 0 以模拟另一个用户的更改。 RowVersion 更改为0x0000000000002B0B

2) I run UPDATE Company SET CompanyName = 'Acme Changed, Inc.' WHERE CompanyId = 0 to simulate a change by another user. RowVersion changes to 0x0000000000002B0B

3)用户A将CompanyName更改为 Acme,The Great!并单击保存(从浏览器)

3) User A changes CompanyName to "Acme, The Great!" and clicks Save (from browser)

4)公司DTO到达Web API服务器时, CompanyName = Acme , 最棒的!和旧的 RowVersion = 0x0000000000002B0A

4) The Company DTO arrives at Web API server with CompanyName = "Acme, The Great!" and the old RowVersion = 0x0000000000002B0A

5)我从数据库中检索公司记录,对其进行更新并保存:

5) I retrieve the Company record from the DB, update it and save it:

public void UpdateCompany(Company updatedCompany)
{
    var dbCompany = Context.Companies.SingleOrDefault(r => r.CompanyId == updatedCompany.CompanyId);
    dbCompany.CompanyName = updatedCompany.CompanyName;
    dbCompany.RowVersion = updatedCompany.RowVersion;  // Set RowVersion to the passed in original RowVersion 0x0000000000002B0A

    try
    {
        DbContext.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        // Expected: exception thrown (but does not happen).
    }
}

代替并发异常,它只是保存记录并将 RowVersion 更新为0x0000000000002B0C。

Instead of a concurrency exception, it just saves the record and updates RowVersion to 0x0000000000002B0C.

我缺少什么?

我需要一种方法来检测更改,删除等,以防止保存脏数据。我想我可以自己动手检查,但是实际的对象很复杂,有许多嵌套的子对象(一个或多个级别)。

I need a way to detect changes, deletion, etc. to prevent saving dirty data. I guess I could roll my own checks, but the actual objects are complex with many nested child objects (one or more levels).

任何有关最佳做法的指针都会也将不胜感激...

Any pointers on best practices on this would also be appreciated...

推荐答案

我已经开始工作了。在我的问题的第5步中,我更改了这一行:

I got this working. In step 5 of my question, I changed this line:

dbCompany.RowVersion = updatedCompany.RowVersion;  

到此:

Context.Entry(dbCompany).OriginalValues["RowVersion"] = updatedCompany.RowVersion;

现在,EF在尝试保存脏数据时抛出DbUpdateConcurrencyException!

Now EF throws a DbUpdateConcurrencyException when trying to save dirty data!

这篇关于尽管有冲突的更新,但EF没有抛出DbUpdateConcurrencyException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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