views:

106

answers:

2

Considering this class

public class XQueries
{
    public IQueryable Query1()
    {
        using (XEntities context = new XEntities())
        {
            return something;
        }
    }

    public IQueryable Query2()
    {
        using (XEntities context = new XEntities())
        {
            return somethingElse;
        }
    }
}

Is a connection to the database created for every (XEntities context = new XEntities()) {...} ? If so what is the correct way to create a static UnitOfWork class so that only 1 connection to exist?

A: 

The Entity Framework opens connections only when required, for example to execute a query or to call SaveChanges, and then closes the connection when the operation is complete.

From Martin Fowler’s book Patterns of Enterprise Application Architecture in respect to Unit Of Work.

When you're pulling data in and out of a database, it's important to keep track of what you've changed; otherwise, that data won't be written back into the database. Similarly you have to insert new objects you create and remove any objects you delete.

You can change the database with each change to your object model, but this can lead to lots of very small database calls, which ends up being very slow. Furthermore it requires you to have a transaction open for the whole interaction, which is impractical if you have a business transaction that spans multiple requests. The situation is even worse if you need to keep track of the objects you've read so you can avoid inconsistent reads.

A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.

Whenever I use Entity Framework for a clients (which I'd admit is rare) the ObjectContext object is the Unit Of Work implementation for the system. That is the ObjectContext will somewhat meet the three statements above. Rather than concentrating too much on the absolutely correct definition using the ObjectContext makes things a little easier for you.

Do some research on DI/IoC and Repository patterns this will give you more flexibility in handling your problem.

heads5150
A: 

You can't create a static unit of work, because by definition a unit of work is a short lived object. Because the EF ObjectContext is designed around the unit of work pattern it is a bad idea to have a single ObjectContext instance during the life time of the application. There are several reasons for this.

First of all, the ObjectContext class is not thread-safe. This means that during the unit of work of one user (in a web app for instance), another user can commit his unit of work. When they share the same ObjectContext, it means that in that situation just half of the changes are persisted and changes are not transactional. When you are lucky the ObjectContext fails and throws an exception. When you are unlucky, you corrupt the ObjectContext and safe and load crap from and to your database and find out when your application is running in production (of course, during testing and staging everything always seems to work).

Second, the ObjectContext has a caching mechanism that is designed for it to be short lived. When an entity is retrieved from the database it stays in the ObjectContext’s cache until that instance is garbage collected. When you keep that instance alive for a long period of time, entities get stale. Especially if that particular ObjectContext instance is not the only one writing to that database.

Steven
Thanks for you answer, so, it is ok to leave it like i posted?
boo
Actually, you can create something like this. See this article: http://nhforge.org/wikis/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.aspx (it's for NHibernate, but it can be adapted to EF as well)
Necros
It depend on your goals, but if it is about performance and correctness, your current solution is correct.
Steven
Just a clarification, A Unit Of Work pattern is definitely not by definition a short lived object. The major benefit of the Unit Of Work pattern (over say a normal ADO.NET transaction) is that it supports creating longer lived "business transactions" that, for example, can span multiple ASP.NET page requests. I haven't worked with EF, but if it dictates short lived Unit Of Work transactions, it is a misleading and incorrect implementation of the pattern.
Ash
@Ash: You are correct. The scope of the Unit of Work is indeed a business transaction and business transaction and business transactions indeed don't have to be short lived. For a web application I still wouldn't advice an `ObjectContext` to outlive a web request, but this does not change the definition of the Unit of Work. Thanks for your comment.
Steven