Member 'CurrentValues' cannot be called for the entity of type 'MyTable' because the entity does not exist in the context

c# dbcontext dbset entity-framework entity-framework-6

Question

I have a MVC application that used Entity Framework v6.0. Whenever a change is made to the DbContext, I override the SaveChanges() method and record the modifications in an audit log. Below is code for part of the audit log recording process:

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;
}

This code usually works, however, when I attempt to make a specific update, I am getting the following error:

Exception Message:

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.

Exception Stack Track:

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()
...

What does the exception message mean? When and why would CurrentValues not be able to be called? What does is mean that entity does not exist in the context?

In MyDatabaseEntities.Context.cs, which extends DbContext, 'MyTable' seems to exist:

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

I checked the Entity Framework model diagram, and 'MyTable' exists there to.

1
1
6/20/2017 4:01:14 PM

Accepted Answer

Thanks to the pointers given in the comments above, I was able to locate where the error was stemming from, and figured out what was triggering the error. The basic answer is that this was caused by a concurrency issue. I was trying to update a MyTable object that had already been deleted in a previous call.

On my web page, I have a table of MyTable object:

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

Each row has a delete button. When a button is clicked, the following actions occur:

  1. Pass in the ID of the object to be deleted.
  2. Get the list of MyTable objects displayed in the HTML table, excluding the object with the ID set to be deleted.
  3. Loop through all the objects and save any modifications, like changes to the Name field.
  4. Delete the MyTable object from the DbSet that has an ID that corresponds to the clicked button.

The problem occurred when a second delete button was clicked before the first set of actions completed. When this happened, there were 2 sets of actions running simultaneously, and the order of events looked something like this:

Action 1: Click button1 (ID to delete = 1)
Action 1: Get the list of MyTable objects to update (includes ID 2)
Action 2: Click button2 (ID to delete = 2)
Action 2: Get the list of MyTable objects to update (still includes ID 1)
Action 1: Update all MyTable objects (ID 2)
Action 1: Delete ID 1
Action 2: Update all MyTable objects - ERROR since ID 1 has been deleted!

I ended up fixing the problem by rearranging the order of some of the events and adding a check to make sure an object still exists in the DbSet and not just the HTML table, before attempting to update it.

2
6/21/2017 5:52:40 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow