Hi,
Ive just started using EF4 with the repository pattern. Im having to call the dispose method after every use of context or wrap code arround in the using block. Can I use the ObjectContext without doing this in every method I write or is there a better way of handling this in the repository.
Also I dont want to pass the ObjectContext to the repository from the UI as well.
views:
117answers:
2To do this as resource effectively as possible without dependency injection, I would suggest that you implement a private, lazy-loading property for the object context.
private ObjectContext _context;
private ObjectContext Context
{ get
{
return _context ?? (_context = new ObjectContext());
}
}
Next, make your repository implement IDisposable
and take care of the object context in your dispose method:
public Repository : IDisposable
{
...
public void Dispose()
{
_context.Dispose();
}
}
Then, you just use the property in all your methods, and wrap usage of your repository in using
statements.
To decrease traffic to the database, you could also factor out the saving to a separate method on the repository, which just forwards the call to the object context. That way you get more control of when data is saved in the UI layer, even though you don't control how. That means you could do
using (var repo = new Repository())
{
repo.AddSomeStuff("this", "is", true);
repo.ChangeSomethingElse("yes, please");
repo.Save();
}
and there would only be one call from EF to the database. On the other hand, if you do
using (var repo = new Repository())
{
repo.AddSomeStuff("this", "is", true);
repo.ChangeSomethingElse("yes, please");
}
nothing happens, which might be confusing.
The general pattern for using an object context is:
public BusinessObject GetSomething(){
using (MyObjectContext context = new MyObjectContext()){
//..do fun stuff
}
}
Which hopefully is the pattern you are using. Calling dispose seems a little overkill when you can just use a "using" statement.
Another option is if you are going to be doing multiple DB queries in a flow. I have seen a pattern where you can reuse the same context within the thread. People basically implement a Thread based singleton pattern and pass around the context. Advantages to this is not having to rebuild the context, as well as some in memory caching. Downside is you could run into concurrency issues. Someone updating something that you have cached internally in EF.
I am guessing the second case doesn't really apply because it sounds like you are writting a small app. (that statement was based on your comments about passing a context from UI...a statement which will scare any good code architect).
If you are interested in a thread based singleton. First learn about the Singleton pattern, and then check out this blog about "DataContext" threads. You will have to change the "DataContext" type to the ObjectContext class but it would work.
EDIT
I will say I overlooked an obvious solution and that would be the below ;). Just using a property based Object Context and playing your repository in a using statement. It would be the same as the using example above, but you would implement IDisoposable.