blog community
Using ADO.NET Entity framework with the repository pattern

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.

First attempt

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.

Improved design

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.

Conclusion

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.


Posted 18-08-2008 8:28 by willemm
Filed under: ,

Comments

Mike wrote re: Using ADO.NET Entity framework with the repository pattern
on 18-09-2008 10:47
I understand the problem. However, Microsoft has adviced againts making the context static. It should be short lived during a unit of work. So as soon as you're done with both the task _and_ the project and everything is saved, then you can dispose of the context. In a web app, I believe you should put it in the httpcontext.items and at the end of the request it can be disposed of. I've not done this, but this is a known pattern for nhibernate's session. What do you think?
willemm wrote re: Using ADO.NET Entity framework with the repository pattern
on 18-09-2008 10:55

I agree with you that you shouldn't let the context live too long. The problem I encountered can also work in the other direction, if you let the context live too long you will most likely get updates in the database you didn't expect in the first place.

For websites it is best to place the datacontext in the HTTP context items and dispose it once the request is completed.

For services I recommend creating the context at the start of the service operation and dispose the context at the end of the service operation right before you return the response.

The solution I wrote will work in both situations and highly recommend when you have a situation like I described in the article.

eXcess wrote re: Using ADO.NET Entity framework with the repository pattern
on 23-09-2008 15:03
I think that for webbased applications a long-running context should not be used since this is running against a multi thread model. I agree. Though, there is nothing wrong using a long-running context, I even think this should be the appropriate method for rich client applications. The whole purpose of the context is just tracking changes, not to be used in simple crud operations thus initializing your object context again and again. This can be a performance killer in big applications.
Coffee, smoke and techilicious burps at 3.47 AM wrote Are you Eager? Or are you Lazy? Or are you both on a case to case basis...??
on 28-01-2009 16:50

Entity Framework, Eager Loading and Lazy Loading, my own 2 cents. For those new to Entity Framework,

Coffee, smoke and techilicious burps at 3.47 AM wrote Are you Eager? Or are you Lazy? Or are you both on a case to case basis...??
on 28-01-2009 17:15

Entity Framework, Eager Loading and Lazy Loading, my own 2 cents. For those new to Entity Framework,

Rady Sadek wrote re: Using ADO.NET Entity framework with the repository pattern
on 03-02-2009 17:33
I think that it is a best practice to have a Repository for each aggregate. Since Project and its tasks make one aggregate try to use only one repository for both.
Freedom Dumlao wrote re: Using ADO.NET Entity framework with the repository pattern
on 18-05-2009 19:59

I don't want to sound rude, but it is urgent that you DO NOT DO THIS if you are building a web application!

Remember that a STATIC member lives in the AppDomain - so all requests to your web application will be using the same instance of ObjectContext!

If user one and user two both add tasks at the same time, one of them (say user one's request) is going to execute SaveChanges() while user two's request is still making changes that are being tracked. This is going to cause the ObjectContext to attempt to persist BOTH user one's desired changes and user two's half changes at the same time, and that is going to cause your app to break.

Instead - why not have your repository take the context as a constructor parameter? Then you can use Inverson of Control and Dependency Injection to create instances of your repositories that have the same context?

Alternatively, you could use the service locator pattern.

willemm wrote re: Using ADO.NET Entity framework with the repository pattern
on 19-05-2009 10:40

The best alternative in my opinion is to not expose the DataContext to the outside world at all. Meaning it should have the following pattern in the repository methods

using(var context = new DataContext()) {

 // Do Stuff

}

So yes, I agree with you.

Keith Patton wrote re: Using ADO.NET Entity framework with the repository pattern
on 31-05-2009 9:03

Hi,

I've posted a blog entry on implementing the repository with POCO classes and EF v4 (beta 1) here if you are interested:

blog.keithpatton.com/.../Entity+Framework+POCO+Repository+Using+Visual+Studio+2010+Net+40+Beta+1.aspx

willemm wrote re: Using ADO.NET Entity framework with the repository pattern
on 31-05-2009 19:07

Thanks Keith for posting about it. I am positive that the pattern described here will work way better in .NET 4.0, so if people have the chance. Use that!

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Powered by Community Server (Commercial Edition), by Telligent Systems