0
votes

I am new to MVC world. So far created few pages successfully and learned a lot. But stuck with an issue. I am developing a master detail webpage where there is a master record and I need to insert multiple detail records at the same time.

I am using MVC entity framework to achieve this. The detail database table ( let's call it D) has identity column ID with Auto Increment. Inserting multiple records works fine without using stored procedure mapping but when I map the stored procedure to insert new records simultaneously it gives me below error.

Error:

"The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges."

the storedgeneratedpattern flag is already set to Identity for ID column of table D. But still no luck.

Can someone please help me with this? Thanks.

1
What version of entity framework do you use? You should go for the latest EF 6. - Vojtěch Dohnal

1 Answers

0
votes

1) Check that you use the latest version of Entity Framework (6). In EF4 there was a problem - see here.

2) Check that you have respective primary key columns marked in your model as identity columns.

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

3) Then:

AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.

This exception text describes your problem. There are some thoughts about this problem here.

The problem is that you add duplicate entities do your DbContext somewhere, probably unintentionaly.

I suggest that you add following methods to your DbContext to see, what is causing troubles:

   //Here you override SaveChanges method of your DbContext
   public partial class MyDbContext 
   {
       public override int SaveChanges()
       {
           DisplayAdded();
           return base.SaveChanges();
       }
   }

    /// <summary>
    /// Returns basic Entity type (for dynamic proxies)
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static Type GetEntityType(object entity)
    {
        if (entity == null)
            return null;
        if (entity != null && ObjectContext.GetObjectType(entity.GetType()) != entity.GetType())
            return entity.GetType().BaseType;
        else
            return entity.GetType();
    }

    /// <summary>
    /// Write added entities and their keys to the output window in Debug mode
    /// </summary>
    public void DisplayAdded()
    {
        Debug.Print("**************************************************************");

        try
        {
            foreach (var dbEntityEntry in ChangeTracker.Entries().Where(x => x.State == EntityState.Added))
            {
                Type t = GetEntityType(dbEntityEntry.Entity); //.GetType().BaseType;
                string baseTypeName = t.Name;

                var keyName = this.ObjectContext.MetadataWorkspace
                    .GetEntityContainer(this.ObjectContext.DefaultContainerName, DataSpace.CSpace)
                    .BaseEntitySets
                    .First(x => x.ElementType.Name.Equals(baseTypeName))
                    .ElementType
                    .KeyMembers
                    .Select(key => key.Name)
                    .FirstOrDefault();
                Debug.Print("{3} {2}: {0} = {1}", keyName, dbEntityEntry.CurrentValues[keyName], baseTypeName, dbEntityEntry.State);
            }
        }
        catch (Exception ex)
        {
            Debug.Print("{0}, {1}", ex.Message, ex.Source);
        }
        Debug.Print("**************************************************************");
    }

This will write to the debug Output window in the Visual Studio all the newly added entities with their respective IDs.