Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在EF 6场景中避免不必要的并发异常?_C#_Concurrency_Entity Framework 6_N Tier Architecture - Fatal编程技术网

C# 如何在EF 6场景中避免不必要的并发异常?

C# 如何在EF 6场景中避免不必要的并发异常?,c#,concurrency,entity-framework-6,n-tier-architecture,C#,Concurrency,Entity Framework 6,N Tier Architecture,我用的是EF6。我有一个两层应用程序,使用WCFSOAP和DTO传输数据。我通过网络发送一个对象图供用户更新,然后将其发送回以保持更改。在这两者之间,我使用AutoMapper在DTO和实体之间进行转换 在持久性方面,我接收DTO并将其解包,因为它包含实体列表。我将其解压缩到适当的实体中,并通过检查id是否为0来检查我们是否正在添加或编辑。到目前为止,我只是盲目地更新了id>0的每个实体 但是,我知道这不是最好的方法,因为它会抛出不必要的并发异常。如果我只是对实体调用update,则rowver

我用的是EF6。我有一个两层应用程序,使用WCFSOAP和DTO传输数据。我通过网络发送一个对象图供用户更新,然后将其发送回以保持更改。在这两者之间,我使用AutoMapper在DTO和实体之间进行转换

在持久性方面,我接收DTO并将其解包,因为它包含实体列表。我将其解压缩到适当的实体中,并通过检查id是否为0来检查我们是否正在添加或编辑。到目前为止,我只是盲目地更新了id>0的每个实体

但是,我知道这不是最好的方法,因为它会抛出不必要的并发异常。如果我只是对实体调用update,则rowversion会得到更新,即使数据库中没有字段实际更改值。这会导致不必要的并发异常。我需要避免这些。所以我需要以某种方式检查一个实体是否真的需要更新。我知道如何检查实体是否需要更新的唯一方法是查询数据库并逐个属性进行检查

我的问题是:我走对了吗?事实上,我真的需要逐个属性检查实体属性以确定它是否需要更新吗?有更简单或更自动的方法吗

在保存更改之前,需要查询每个实体的数据库,这让我感到沮丧。也许我错过了什么

以下是我的代码示例:

var ws = saveRequest.Workspace;
var td = saveRequest.ToDelete;

using (var db = new EngineeringContext())
{
    var ass = Attach<JobAssembly>(db, db.JobAssemblies, ws.Assemblies.ToDomain());
    var opr = Attach<JobOperation>(db, db.JobOperations, ws.Operations.ToDomain());
    var mtl = Attach<JobMaterial>(db, db.JobMaterials, ws.Materials.ToDomain());

    Delete<JobAssembly>(db, td.Assemblies.ToDomain());
    Delete<JobOperation>(db, td.Operations.ToDomain());
    Delete<JobMaterial>(db, td.Materials.ToDomain());

    try
    {
        db.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        throw new Exception("Sync Error: The data failed to save due to changes by another user.", ex);
    }

    ws.Assemblies = ass.ToDto();
    ws.Operations = opr.ToDto();
    ws.Materials = mtl.ToDto();
}
其中“附加”和“删除”如下所示:

db.Entry<T>(entity).State = EntityState.Modified; // .Deleted for deletes.

ToDomain和ToDto是将域实体映射到DTO和viceversa的扩展。

如果不显示正在执行的操作,很难确定要修复什么。e、 你在使用SaveChanges吗?我在保存和异常发生的地方添加了代码。你必须查询数据库,或者实体必须有某种机制来跟踪更改本身。EF中曾经有自跟踪实体,但它们已被弃用。