Thursday, 9 September 2010

Discarding Changes to ObjectContext in Entity Framework

Occassionally, when calling SaveChanges() on an Entity Framework ObjectContext throws an exception within a try... catch block you may find that a subsequent call to SaveChanges only throws the same exception. How can you get round this?

Basically, the problem stems from the fact that you made changes to your ObjectContext which the database then rejected (most likely situation, but not exclusively. There may be connectivity issues etc, etc). However, just because you caught the exception doesn't mean that your ObjectContext isn't still in an invalid state. Unless you've made several changes to your ObjectContext object before calling SaveChanges() you can simply call AcceptAllChanges() on the object context before carrying on. This basically tells the ObjectContext to let go of all the changes made to it and basically clears the slate, allowing you to make new changes to the object and subsequently save the changes.

ObjectContext context = new Entities();
Client newClient = Client.CreateClient("johndoe", "John", "Doe", ... various other properties);
//This username is already taken and will produce a
//UniqueConstraintViolationException
try{
context.AddToClients(newClient);
context.SaveChanges();
}
catch(UniqueConstraintViolationException)
{
context.AcceptAllChanges();
//Clears the changes that caused the exception
//Look up the client with the username "johndoe" and update this client's details
//with the details passed through
}