无法为“MyTable”类型的实体调用成员“CurrentValues”,因为该实体在上下文中不存在

时间:2017-06-20 15:07:47

标签: c# entity-framework entity-framework-6 dbcontext dbset

我有一个使用Entity Framework v6.0的MVC应用程序。每当对DbContext进行更改时,我都会覆盖SaveChanges()方法并将修改记录在审核日志中。以下是部分审核日志记录过程的代码:

public override int SaveChanges()
{
    var ChangesEntities = ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted
        || e.State == EntityState.Modified
        || e.State == EntityState.Added).ToList();

    foreach (DbEntityEntry entry in ChangesEntities)
    {
        if (entry.State == EntityState.Modified)
        {
            SetCorrectOriginalValues(entry);
        }

        ...
    }

    ...

    return base.SaveChanges();
}

void SetCorrectOriginalValues(DbEntityEntry Modified)
{
    var values = Modified.CurrentValues.Clone();
    Modified.Reload();
    Modified.CurrentValues.SetValues(values);
    Modified.State = EntityState.Modified;
}

此代码通常有效,但是,当我尝试进行特定更新时,我收到以下错误:

异常消息:

Member 'CurrentValues' cannot be called for the entity of type 'MyTable' because the
entity does not exist in the context.
To add an entity to the context call the Add or Attach method of DbSet.

异常堆栈跟踪:

at System.Data.Entity.Internal.InternalEntityEntry.get_CurrentValues()
at System.Data.Entity.Infrastructure.DbEntityEntry.get_CurrentValues()
at MyDatabaseName.DataLibrary.MyDatabaseEntities
    .SetCorrectOriginalValues(DbEntityEntry Modified)
at MyDatabaseName.DataLibrary.MyDatabaseEntities.SaveChanges()
...

异常消息是什么意思?何时以及为什么CurrentValues无法被调用?什么意味着实体在上下文中不存在?

在扩展DbContext的MyDatabaseEntities.Context.cs中,'MyTable'似乎存在:

public virtual DbSet<MyTable> MyTables { get; set; }

我检查了Entity Framework模型图,并在那里存在'MyTable'。

1 个答案:

答案 0 :(得分:2)

感谢上面评论中给出的指针,我能够找到错误所在的位置,并找出触发错误的原因。基本答案是这是由并发问题引起的。我试图更新之前调用中已删除的MyTable对象。

在我的网页上,我有一个MyTable对象表:

ID   | Name | Delete Button
---- | ---- | -------------
1    | abc  | button1
2    | xyz  | button2

每行都有一个删除按钮。单击按钮时,将执行以下操作:

  1. 传入要删除的对象的ID
  2. 获取HTML表格中显示的MyTable个对象的列表,不包括要删除ID的对象。
  3. 遍历所有对象并保存所有修改,例如对Name字段的更改。
  4. MyTable中删除DbSet对象,该对象的ID与所点击的按钮对应。
  5. 在第一组操作完成之前单击第二个删除按钮时出现问题。当发生这种情况时,有两组动作同时运行,事件的顺序如下所示:

    操作1:点击button1(要删除的ID = 1)
    操作1:获取要更新的MyTable对象列表(包括ID 2)
    操作2:点击button2(要删除的ID = 2)
    操作2:获取要更新的MyTable对象列表(仍包含ID 1)
    操作1:更新所有MyTable对象(ID 2)
    操作1:删除ID 1
    操作2:更新所有MyTable对象 - 错误,因为ID 1已被删除!

    我最终通过重新排列某些事件的顺序来修复问题,并在尝试更新之前添加一个检查以确保对象仍然存在于DbSet而不仅仅是HTML表中。 / p>