Using DbContext To Query Model-First/Database-First EDMX Models

October 14, 2012 — Leave a comment

If you are using Visual Studio 2012 and creating your model with Entity Framework 4.4.0.0+, this post is not for you. As of  version 4.4.0.0 models are created using DbContext by default.

For those who are upgrading your projects to .Net 4.0 / .Net 4.5 and are currently using a model-first or
database-first EDMX model, you have the possibility of using a DbContext  to query your ObjectContext.

The following example demonstrates how to instantiate your DbContext and how to query it.

class Program
{
    static void Main(string[] args)
    {
        //Create the ObjectContext
        var objectContext = new EdmxModelContainer();

        //Create the DbContext 
        bool dbContextOwnsObjectContext = true;
        var dbContext = new DbContext(objectContext, dbContextOwnsObjectContext);

        // Query using the ObjectContext
        var studentList = objectContext.Schools
                                        .Include("Classed")
                                        .SelectMany(s => s.Students)
                                        .ToList();

        // The same Query using the DbContext
        var students = dbContext.Set<School>()
                                    .SelectMany(s => s.Students)
                                    .Include(s => s.Classes)
                                    .ToList();

        Console.WriteLine("Results are the same: " 
            + (students.Intersect(studentList).Count() == students.Count())
            + " " 
            + studentList.Count);
            
        // Since we created a DbContext that owns the ObjectContext
        // the ObjectContext will be Disposed with the DbContext
        dbContext.Dispose();

        Console.ReadLine();
    }
}

Whenever you work with Entity Framework ObjectContext or DbContext its important to Dispose them when you are done with them. Failure to do so can result in weird behavior like reaching the limit of concurrent connections on your database.

The code could be rewritten to look like the following

class Program
{
    static void Main(string[] args)
    {
        List<Student> studentList;
        
        using(var ctx = new EdmxModelContainer())
        {
            // Query using the ObjectContext
            studentList = ctx.Schools
                .Include("Classed")
                .SelectMany(s => s.Students)
                .ToList();
        }

        List<Student> students;
            
        using (var ctx = DbContextFactory.Make<EdmxModelContainer>())
        {
            // The same Query using the DbContext
            students = ctx.Set<School>()
                .SelectMany(s => s.Students)
                .Include(s => s.Classes)
                .ToList();
        }

        Console.WriteLine("Results are the same: " 
            + (students.Intersect(studentList).Count() == students.Count())
            + " " 
            + studentList.Count);
        
        Console.ReadLine();
    }
}

The DBContextFactory below is an attempt at packaging the creation and wrapping logic for the DbContext. It’s limited to using the default values to create the ObjectContext instances.

public class DbContextFactory
{
    public static DbContext Make(ObjectContext context, bool ownsContext = true)
    {
        return new DbContext(context, ownsContext);
    }

    public static DbContext Make<TContext>() where TContext : ObjectContext, new()
    {
        var ctx = new TContext();
        return new DbContext(ctx, true);
    }
}

No Comments

Be the first to start the conversation!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.