unique index violation, attempting to insert object graph on new context
Referencing the code below, I have a list of Error
objects that has been instantiated for insertion. Each error has been assigned an ErrorType
object which has been retrieved from the database. When I attempt to insert the list of errors on a new context I get an exception from the database of unique index violation
on ErrorType. This makes sense as the new context assumes that the ErrorType object is also new, not knowing that it already exists in the database. I have attempted to solve this by using Attach on ErrorType, as well as doing a re-query of all ErrorTypes in the database, however that didn't seem to help. I ran the SQL Profiler and still see that EF is issuing an insert statement on the ErrorType entity.
Edit: I also added "Try 1.5" which in conjunction with "Try 1" actually does the job. I still don't understand why I have to go back and change all error.ErrorType references to point to the locally created and attached ErrorType object. I understand that the original ErrorType and the locally created one are different objects in memory, but they share the same PrimaryKey, so my assumption was that Entity Framework understands that they are one and the same.
It also seems that I am unable to Attach the original FileErrorType (as opposed to the local) because it then attempts to attach the entire graph, that's why I chose to create a local copy of the FileErrorType object that has the same primary key value.
void Ins开发者_StackOverflowertErrors(IList<Error> errors)
{
using(var context = ....)
{
//Try 1:
//asuming there is only 1 error type (true in my example)
//ErrorType et = new ErrorType();
//ErrorTypeId is the primary key
//et.ErrorTypeId = errors[0].ErrorType.ErrorTypeId;
//context.ErrorTypes.Attach(et);
//Try 1.5
//If I also add the followin code to Try 1, everything works, but I'm not sure why
//foreach(var e in errors)
//{
// error.ErrorType = et; //reassign to the locally created ErrorType object that has been Attached
//}
//Try 2:
//var errorTypes = context.ErrorTypes.ToList();
foreach(var e in errors)
{
context.Errors.AddObject(e);
}
context.SaveChanges();
}
}
When you add the Errors, they and the associated ErrorTypes are marked as added and are inserted into the database on the call to SaveChanges.
Call attach on all of the ErrorType instances once they are associated with the context. This will change the state of the ErrorTypes to Unmodified and prevent them from being inserted during SaveChanges.
精彩评论