在VS 2012中调试时收到此异常

具有相同键的对象已存在于ObjectStateManager中。 ObjectStateManager无法使用相同的键跟踪多个对象。

//_dbSet declaration: 

    private readonly IDbSet<T> _dbSet;


//Method parameter

    public virtual void Update(T entity)


//method fragment   



 public virtual void Update(T entity)
    {
        if (Entities == null) return;

        var entry = Entities.Entry(entity);

        switch (entry.State)
        {
            case EntityState.Modified:
                var currentValues = entry.CurrentValues.Clone();
                entry.Reload();
                switch (entry.State)
                {
                    case EntityState.Detached:
                        Entities.Entry(entry).State = EntityState.Modified;
                        break;
                    default:
                        entry.Reload();
                        entry.CurrentValues.SetValues(currentValues);
                        break;
                }
                break;
            case EntityState.Detached:
                _dbSet.Attach(entity); /*Here is the thing*/
                entry.CurrentValues.SetValues(entity);
                break;
        }
        Entities.Commit();
    }

我花了将近一个星期的时间来尝试使用以下模式来解决乐观并发:DbFactory,工作单元,DI,通用存储库,但没有得到结果。

===============>>#1 票数:0

我认为异常消息很清楚:

具有相同键的实体(即,映射到相同数据库记录的实体)已经加载并附加在目标DbSet

在这种情况下,您决定做什么完全取决于您:

  • 您可以获取已经加载的等效项,并修改附加的等效项的值以匹配entity实例(或更复杂的事物);
  • 您可以分离等效的已加载条目,然后附加参数entity
  • 您可以跳过它;

===============>>#2 票数:0

代码难闻;

第一个switch语句使用entry.State并检查实体是处于修改状态还是处于分离状态; 然后在修改后的情况下,将创建一个新的switch语句来检查实体是否已分离或处于其他状态。

异常没有说明乐观并发性。 相反,它指出您正在尝试将实体附加到对象上下文,并且上下文中已经存在具有相同键的实体。

===============>>#3 票数:0

我要感谢所有人,他们将宝贵的时间花在了我的头上。 这是一篇新文章,阐明了我对通用存储库模式中的并发更新方法的最终解决方案。 多亏了本文,一切都没有丢失: 按属性寻找实体的键

那非常有用: RoccoC5


private object GetKeyValue(T entity)
    {
        var key =
            typeof(T).GetProperties().FirstOrDefault(
                p => p.GetCustomAttributes(typeof(KeyAttribute), true).Length != 0);
        return (key != null) ? key.GetValue(entity, null) : null;
    } 

公共虚拟无效Update(T实体){如果(实体== null)返回;

        var key = GetKeyValue(entity);
        var originalEntity = _dbSet.Find(key);
        Entities.Entry(originalEntity).CurrentValues.SetValues(entity);
        Entities.Commit();
   }

  ask by Felix Aballi translate from so

未解决问题?本站智能推荐:

1回复

处理乐观并发MVC编辑表

我的下面的编辑表单有问题,它从不捕获DbUpdateConcurrencyException 。 我究竟做错了什么? 类 控制者 我还将RowVersion列的“并发模式”设置为固定 编辑 我还将catch块异常更改为通用异常,现在收到以下错误:
1回复

如何避免EF中新添加记录的乐观并发错误

我在MVC 5项目中使用Entity Framework 6,在Experiment和FileAttachment之间存在实体关系(一个Experiment可以提供多个FileAttachment)。 在“编辑实验”记录期间,我加载了一个包含两个实体的ViewModel并在编辑模式下列出了该实
1回复

我应该如何处理这个实体框架代码中的这种乐观并发错误?

在某些使用EF4的 存储库模式项目中,我有以下pseduo代码。 很简单,但是我遇到了运行时错误: ConcurrencyException:存储,更新,插入或删除语句影响了意外的行数(0)。 现在,这就是正在发生的事情:- EF4的两个实例同时在应用程序中运
1回复

实体框架乐观并发异常未发生

我们有一个ASP.Net MVC应用程序,它使用EF4作为其数据访问层,我们看到在我们认为它们应该是没有抛出OptimisitcConcurrencyExceptions的意外行为。 我们已将问题简化为以下代码... 这是我们的MVC应用程序中发生的相当简单的版本,但是会出现同样的
1回复

将视图转换为表并保存更改为我带来了乐观的并发异常

我正在使用Entity Framework 4(使用自我跟踪实体),并访问视图,即两个表的合并。 因此,当我更新视图的信息时,我将视图的STE发送到可访问数据库的存储库。 我已经完成以下工作: 当收到包含更新信息的视图时,将创建STE1和STE2。 当我创建STE时,如何使用添加
3回复

在Entity Framework中删除对象时的并发性

我正在使用实体框架开发一个Web应用程序。 我加载一个对象列表并将其绑定到转发器以显示所有项目的摘要。 用户可以单击转发器中的每个项目的编辑图标或删除图标。 例: 第1项| 编辑| 删除 第2项| 编辑| 删除 ... 使用rowversion列进行并发
1回复

Model First方法中的EF Concurrency Handling with Timestamp属性

我试图在ASP.NET MVC应用程序中实现使用Entity Framework处理并发中给出的解决方案。 文章说: 将跟踪属性添加到部门实体 在Models \\ Department.cs中,添加一个跟踪属性: Timestamp属性指定此列将包含在发送到
4回复

如何使用一个功能使用相同的按钮名称进行插入和更新

我有一个名为“保存”的按钮。 当您双击(Tab1)中的网格时。 数据正在加载到文本框中,以便您可以在Tab2上进行编辑。 所以我所有的字段都在Tab2上,它允许您保存到数据库中。 当您加载页面并单击Tab2时。 您将填写所有文本框,然后单击“保存”按钮。 现在我想使用相同的功能使用称
1回复

克服实体框架中缺少ConflictMode.ContinueOnConflict实现的模式?

Linq To SQL的DataContext在SubmitChanges上有一个重载,当抛出乐观并发异常时,它允许更新继续进行,并为开发人员提供了一种机制,可以在一个Try Catch块中解决冲突。 甚至WCFDataServicesContext的SaveChanges方法都有一个Sa
3回复

如何解决C#.NET N层应用程序中的乐观并发更新?

大家好 在c#.net VS 2008中,我正在开发一个N层CRM框架解决方案,完成后我想共享它。 该体系结构基于: 数据访问层,实体框架,业务逻辑层,WCF,最后是表示层(Win窗体)。 在我读过的某处,由于乐观并发更新(具有相同数据的多个客户端事务),导致超过2层的层