0

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.

Vojtěch Dohnal
  • 7,867
  • 3
  • 43
  • 105

1 Answers1

0

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.

Community
  • 1
  • 1
Vojtěch Dohnal
  • 7,867
  • 3
  • 43
  • 105
  • Hi Vojtěch, tried using EF6 with MVC4 & VS 2012 but it screw up my objects and all models that I creates. I believe I need VS 2015 with MVC5 and EF6 to see if works. Please correct me if I am wrong. – ASHISH PATEL Apr 29 '16 at 07:05
  • @ASHISHPATEL You can use VS 2012 with MVC 5. http://stackoverflow.com/questions/19102831/how-to-install-asp-net-mvc-5-in-visual-studio-2012 – Vojtěch Dohnal Apr 29 '16 at 07:13
  • But this problem is more Entity framework problem then MVC problem. `when I map the stored procedure to insert new records simultaneously it gives me below error.` you did not post any code for this, so it is hard to tell. – Vojtěch Dohnal Apr 29 '16 at 07:18
  • i used VS 2015 with latest EF6 version but end up with same problem. – ASHISH PATEL May 02 '16 at 03:10
  • please check STEP 10 on http://www.dotnetawesome.com/2015/09/how-to-create-master-detail-entry-form-in-aspnet-mvc4.html blog. This is exactly what I am doing but using mapped stored procedures. But I get the error. Hope this helps. – ASHISH PATEL May 02 '16 at 03:17
  • @ASHISHPATEL There is no stored procedure used in that example & that is where you have problem as you wrote. – Vojtěch Dohnal May 02 '16 at 06:19
  • I know that the example I provided is not using stored procedure. But using stored procedure should not restrict me and should not throw an error inserting the records in the database specially when the ID field is set as identity in edmx. Any clue why it is throwing an error when using the stored procedure? – ASHISH PATEL May 02 '16 at 23:26
  • @ASHISHPATEL So you use `.MapToStoredProcedures();` fluent API method? You should include that in your question, How does the generated stored procedure look like in the database? Add some sample code to your question, see http://stackoverflow.com/help/mcve – Vojtěch Dohnal May 03 '16 at 08:58