Microsoft released the ADO.NET entity framework with their latest service pack and I’m quite happy with what they have done so far. The entity framework helps reduce code complexity for creating entities and it also saves you the work of having to write all the mapping code yourself.
One of the things I tried out was to use the Repository pattern (Well known to the NHibernate community) to make the framework easier to use by reducing the amount of methods that are available.
The first attempt was pretty straight forward. Create a new model and two repositories that access the various entities in the model. I used interfaces here to maximize testability. You can of course leave the interfaces out if you don’t want the clutter in your code.
As part of my first design I used a single object context with each call inside a using statement, this ensures that the garbage collector cleans up after I’m done thus reducing the amount of memory needed. However this caused some really weird behavior when building the following scenario:
I have a method that creates a new task and attaches it to a project. The project is retrieved from the project repository class and the task is created by task repository. After the task is created the program calls the save method on the task repository to save the task. You’d think that this works perfectly. At least I thought this would work.
What really happens is that as soon as you attach the project instance to the Project property of the task, the task is registered with the object context of the project. That object context is now tracking the changes and correctly detects that the task is new and should be added when SaveChanges is called on the object context. However, I am not calling SaveChanges on the object context of the project, but rather on the Task object context. The task is not tracked by that context and thus not saved to the database.
The first attempt left me with a rather large hole in my design. Clearly this wasn’t the only scenario where this would go wrong, so I had to change something to make it work. It’s a trade-off in memory usage, but if you move the object context to a central static class and let the repository classes use that instance the problem is solved. The new design looks like this:
There’s one catch though. You have to manually dispose the object context once the application exits. Or in the case of a service, dispose the context once you have constructed the reply message and no longer need the object context.
The object context in ADO.NET Entity framework is a great way of working with the entities and keeping track of changes made to any of the entities. However it will give you a major headache when you don’t have a single object context for the whole domain model. Having one object context isn’t all that either, because hanging updates from one operation will most likely cause problems when performing the next operation. I have seen this too and I haven’t got a solution for that at the moment.
I hope this helps to prevent some of the troubles that developers have when they start using ADO.NET entity framework for the first time.