Saturday, August 06, 2011

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.

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.

I got this error while working with WCF, Entity Framework 4.0 and C#.Net 2010, I had one object bind with parent child relationship and when I tried to delete record from child object first and then from parent object, that time I got this error.

Basically when you have relational entity object and want to execute all delete operation in single transaction, then you have to attach the object into the context and then remove it, instead of doing ApplyChanges(), this method will maintain the object key’s into ObjectStateManager and when you try to remove data from parent object then It will throw this error. I spend enough time to find the solution of this error.

Let’s say you have object structure like below

publicclassCountry

{

//Default Constructor

public Country() { CountryState = newList<States>(); }

publicstring Name { get; set; }

publicint Id { get; set; }

publicList<States> CountryState { get; set; }

}

publicclassStates

{

publicstring Name { get; set; }

publicint Id { get; set; }

}

All data I have in “countryObject”

//Load this object with actual data

List<Country> countryObject = newList<Country>();

Now the code I got this error is below

using (var ctx = DataBaseContext)

{

using (var tc = newTransactionScope())

{

foreach (Country con in countryObject)

{

foreach (States sat in con.CountryState)

{

//Delete Data from CHIILD Table/Object

sat.MarkAsDeleted();

ctx.States.ApplyChanges(sat);

}

//Delete Data from PARENT Table/Object

con.MarkAsDeleted();

ctx.Country.ApplyChanges(con); //ERROR

}

//Save the Changes

ctx.SaveChanges();

//Commit the transaction

tc.Complete();

}

}

The code I resolved this error

using (var ctx = ServiceUtility.Context)

{

using (var tc = newTransactionScope())

{

foreach (Country con in countryObject)

{

foreach (States sat in con.CountryState)

{

//Delete Data from CHIILD Table/Object

sat.MarkAsDeleted();

ctx.States.Attach(sat);

ctx.States.DeleteObject(sat);

}

//Delete Data from PARENT Table/Object

con.MarkAsDeleted();

ctx.Country.Attach(con);

ctx.Country.DeleteObject(con);

}

//Save the Changes

ctx.SaveChanges();

//Commit the transaction

tc.Complete();

}

}

Note: if you use ctx.SaveChanges(); in a loop or after every Deleteobject() method then you might get following error"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries."