Today I was looking at a post in the forums where someone asked a very natural and common question about the EF that I end up answering pretty frequently. So I decided to put my answer here on my blog to make it easier to refer back to the answer in the future. The question was essentially this:
I’m building a silverlight client (but it could just as easily be a rich client or an ajax app or any other client of a WCF service) with a WCF service on the mid-tier that uses the EF to persist changes to a database. I can easily write a WCF service method to retrieve entities, and I can also create one which will add new entities to the database by just calling AddObject and then SaveChanges, but I can’t figure out how to do an update. I was hoping there would just be an UpdateObject method or something like that. What do I do?
Unfortunately this is more difficult than we'd like it to be in EF3.5 (the first release). It's a bit difficult because the problem space is more complicated under the covers than it seems to be on the surface, so you have to think carefully about a few things. That said, the EF API could help more in these scenarios, so in EF4 we're working on a series of improvements which you can read about in posts on the EF Design blog such as this one: http://blogs.msdn.com/efdesign/archive/2009/03/24/self-tracking-entities-in-the-entity-framework.aspx In the meantime, there are three important things you need to think about:
All of this amounts to tracking this information on the client side, communicating it back to your mid-tier through your WCF service methods, and then replaying information to the ObjectContext so the changes can be persisted. If you skip option #3 for now (one of the hardest parts with EF3.5 and something which can occasionally be skipped if you are willing to just have WCF service methods which operate on one entity or which treat all entities in the graph the same way--so you have separate methods for add, update and delete), then you already know how to do the add method. The delete method is also pretty straight forward, you just need to call Attach on the entity you pass to the method to bring it into the context and then call DeleteObject on it and SaveChanges. The interesting method, as you mention, is update...
The simplest but not terribly efficient way to solve the update method is to make a copy of the entity on the client before you make any changes so that at the time you want to update things you have both a copy of the original version of the entity and the modified one. Then your update service method can look something like this:
void Update(MyEntity original, MyEntity updated){ using (var context = new MyEntities()) { context.Attach(original); context.ApplyPropertyChanges(updated); context.SaveChanges(); }}