Another clever pattern for dealing with EF Change Tracking across processes

The Swiss MSDN team released an awesome Hands on Lab (thanks Danny for the pointer). One of the features of the lab was an n-tier solution. I had to see how they did it.

They are using a shallow graph - i.e. no graph at all, so only have to deal with single entities. Then what they are doing is passing a pair of collections back to the server for an update. The first collection is the original entities and the second is the current. If the the current entities contain an entity that does not exist in the original collection it needs to be added. If the current collection is missing an entity that is in the original collection it needs to be deleted. And if there is a match then it is either updated or unchanged and a quick apply property changes will do the trick there.

This is clever and works and will be find for many scenarios where graphs aren't involved ...unless you are concerned about the size of the payload. With EFv1 we have to pay the price *somewhere*. The choices are

1) to do what this lab is doing and pass the original entities back where the price is the size of the data going through the pipe to the service. Remember there are no graphs here. You can use this pattern with graphs but you will have more work digging through and comparing and an even larger amount of data coming through the pipe.

2) to use a pattern that I employed in an early chapter of my book which is to make assumptions (id=0 means it's new, id<>0 means it's either unchanged or an update) and additionally pass back an array of ids of entities to delete. Once those decisions are made, I hit the db to get fresh data and update against that. So the price there is first the guessing game and second the hit to the db. I am using graphs here.

3) Another option, which I do in one of the last chapters of my book is to use DTOs with a state flag to eliminate the guessing game and simplify some of the work with relationships. Then again, I hit the database for fresh data to update against. The price here again is the extra db hit and also some extra work on the server side creating dto classes and migrating from entities to dtos and back again.

4) The last option which I have seen John Papa and Tony Sneed use is similar to my #3 but they do not hit the db. Instead they force all fields in every changed entity to become "modified" and update that way. The price here is that you are sending more data from the service to the database than necessary and more challenges working with children.

#3 and #4 are most comparable and again, it's just a matter of performance in your particular scenario that is going to help you decide.

Don't forget there's a #5 which is to use EF within another framework altogether - a framework that already knows how to do all of the change tracking, updates, persistence etc.

I spent two years fighting against the solution of hitting the db again. I HATE database hits. But in the end I decided that it was the least of the possible evils.

Much will change in EF4, that's for sure!

Technorati Tags:

#1 Steve on 5.28.2009 at 12:05 AM

What about using a unit of work pattern - and object that holds changed/added/delete entities.

Controller tracks changes by registering changed, new and deleted entities that are then sent to the service layer -> repository for persisting those changes to the database.