简体   繁体   English

EF 代码优先 DbUpdateConcurrencyException.Entries 中可以有多个实体吗?

[英]EF code-first can there be multiple entities in DbUpdateConcurrencyException.Entries?

We are using EF 6.x with RefactorThis.GraphDiff ;我们将 EF 6.x 与RefactorThis.GraphDiff一起使用; so that a related entity-tree is saved/updated using EF.以便使用 EF 保存/更新相关的实体树。

We have added RowVersion for each table to capture the concurrency as we are using UoW + Repository pattern with disconnected contexts.我们为每个表添加了 RowVersion 以捕获并发性,因为我们在断开连接的上下文中使用 UoW + Repository 模式。

The solution provided at this page has the following code-snippet:页面提供的解决方案具有以下代码片段:

{ {

var entry = ex.Entries.Single(); var entry = ex.Entries.Single();

} }

My question is - is it possible to get more than one entry in the "ex.Entries"?我的问题是 - 是否有可能在“ex.Entries”中获得多个条目? Will all of them be having Concurrency issue?他们都会有并发问题吗?

Also, additional question - is it possible that RowVersion of "DB" value be smaller than "Original" values?另外,附加问题 - “DB”值的 RowVersion 是否可能小于“原始”值?

No, you still cannot get more then one entry at a time.不,您仍然不能一次获得超过一个条目。 Unless they fix it, github issue: https://github.com/do.net/efcore/issues/1002除非他们修复它,github 问题: https://github.com/do.net/efcore/issues/1002

But you still can catch DbUpdateConcurrencyException as many times as it will be raised, deciding every time how to resolve conflict.但是您仍然可以多次捕获 DbUpdateConcurrencyException,因为它会被引发,每次都决定如何解决冲突。 Let's get the code sample from here and slightly change it:让我们从这里获取代码示例并稍微更改它:

using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;

using var context = new PersonContext();

// Fetch a person from database and change phone number
var person1 = context.People.Single(p => p.Id == 1);
person1.PhoneNumber = "555-555-5556";
var person2 = context.People.Single(p => p.Id == 2);
person2.PhoneNumber = "555-555-5557";

// Change the person's name in the database to simulate a concurrency conflict
context.Database.ExecuteSqlRaw(
    "UPDATE dbo.People SET FirstName = 'Jane' WHERE PersonId = 1;" +
    "UPDATE dbo.People SET FirstName = 'John' WHERE PersonId = 2;");

var saved = false;
while (!saved)
{
    try
    {
        // Attempt to save changes to the database
        context.SaveChanges();
        saved = true;
    }
    catch (DbUpdateConcurrencyException ex)
    {
        foreach (var entry in ex.Entries)
        {
            if (entry.Entity is Person)
            {
                var proposedValues = entry.CurrentValues;
                var databaseValues = entry.GetDatabaseValues();

                foreach (var property in proposedValues.Properties)
                {
                    var proposedValue = proposedValues[property];
                    var databaseValue = databaseValues[property];

                    // TODO: decide which value should be written to database
                    // proposedValues[property] = <value to be saved>;
                }

                // Refresh original values to bypass next concurrency check
                entry.OriginalValues.SetValues(databaseValues);
            }
            else
            {
                throw new NotSupportedException(
                    "Don't know how to handle concurrency conflicts for "
                    + entry.Metadata.Name);
            }
        }
    }
}

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

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