O'Reilly logo

Programming Entity Framework: DbContext by Rowan Miller, Julia Lerman

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Looking at Some Highlights of the DbContext API

DbContext API is mostly targeted at simplifying your interaction with Entity Framework, both by reducing the number of methods and properties you need to wade through and by providing simpler ways to access commonly used tasks. In previous versions of Entity Framework, these tasks were often complicated to discover and code. We have a few favorites that act as great ambassadors to the new API, which we’ll share with you here. You’ll learn more about these as you work your way through the book.

Note

The samples used in this chapter are for explanation purposes only and not intended for you to perform in Visual Studio. Beginning with the next chapter, you’ll find walkthroughs that you can follow in Visual Studio.

Let’s start by looking at how the DbContext API simplifies the context that we define and work with. We’ll compare the ObjectContext and DbContext based context classes from the model we’ll be using in this book, based on BreakAway Geek Adventure’s business applications. We’ll expose queryable sets of People, Destinations, and Trips based on a Person class, a Destination class, and a Trip class.

Example 1-1 shows a subset of the BreakAwayContext class used in Entity Framework 4, based on an ObjectContext. It wraps up some known types into ObjectSets, which you can query against.

Example 1-1. BreakAwayContext that inherits from ObjectContext

public class BreakAwayContext : ObjectContext
{
  private ObjectSet<Person> _ people;
  private ObjectSet<Destination> _destinations;
  private ObjectSet<Trip> _trips;

  public ObjectSet<Person> People
  {
    get { return _people ?? (_people = CreateObjectSet<Person>("People")); }
  }

  public ObjectSet< Destination > Contacts
  {
    get { return _ destinations?? (_destinations =
              CreateObjectSet< Destination >("Destinations")); }
  }

  public ObjectSet<Trip> Trips
  {
    get { return _ trips?? (_trips = CreateObjectSet<Trip>("Trips")); }
  }
}

Example 1-2 shows the same context and sets using a DbContext and DbSets instead. Already you can see a big improvement. You can use automatic properties with DbSet (that’s the simplified get;set; pattern), something you can’t do with ObjectSet. This makes for much cleaner code right out of the gate. There is a CreateDbSet method that’s relative to CreateObjectSet, but you aren’t required to use it for the purpose of creating a DbSet when you have no other logic to apply.

Example 1-2. BreakAwayContext inheriting from DbContext

public class BreakAwayContext : DbContext
  {
    public DbSet<Person> People { get; set; }
    public DbSet<Destination> Destinations { get; set; }
    public DbSet<Trip> Trips { get; set; }
}

Reducing and Simplifying Ways to Work with a Set

In Entity Framework 4, there are a number of tasks that you can achieve from both ObjectContext and ObjectSet. For example, when adding an object instance to a set, you can use ObjectContext.AddObject or ObjectSet.AddObject. When adding an object into the context, the context needs to know which set it belongs to. With ObjectContext.AddObject, you must specify the set using a string, for example:

context.AddObject("Trips", newTrip);

When ObjectSet was introduced in Entity Framework 4, it came with its own AddObject method. This path already provides knowledge of the set so you can simply pass in the object:

context.Trips.AddObject(newTrip);

With this new method available, the only reason ObjectContext.AddObject continued to exist in Entity Framework 4 was for backward compatibility with earlier versions. But developers who were not aware of this reason were confused by the fact that there were two options.

Because the DbContext API is new, we don’t have to worry about backward compatibility, so the DbContext does not have a direct method for adding an object. Additionally, rather than providing the clunky AddObject method in DbSet, the method name is now simply Add:

context.Trips.Add(newTrip);

ObjectContext also has AttachObject and DeleteObject. DbContext does not have these methods either. DbSet has Attach and Remove, which are equivalent to ObjectSet’s Attach and Delete Object. You’ll learn more about interacting with DbSet beginning in Chapter 2.

Retrieving an Entity Using ID with DbSet.Find

One task that developers perform frequently is retrieving an entity by providing its key value. For example, you may have access to the PersonId value of a Person in a variable named _personId and would like to retrieve the relevant person data.

Typically you would construct and execute a LINQ to Entities query. Here’s a query that uses the SingleOrDefault LINQ method to filter on PersonId when executing a query on context.People:

context.People.SingleOrDefault(p => p.PersonId == _personId)

Have you written that code so often that you finally wrote a wrapper method so you could pass the key value in and it would execute the LINQ query for you? Yeah, us too. Now DbSet has that shortcut built in with the Find method, which will return an entity whose key property matches the value passed into the method:

context.People.Find(_personId)

Find has another benefit. While the SingleOrDefault query above will always query the database, Find will first check to see if that particular person is already in memory, being tracked by the context. If so, that’s what will be returned. If not, it will make the trip to the database. Under the covers, DbContext is executing logic on ObjectContext to perform the necessary tasks. You’ll learn more about DbSet.Find in Chapter 2.

Avoiding Trolling Around the Guts of Entity Framework

These are just a few examples of how much more natural it is to work with the DbContext API than the ObjectContext API. If you read Programming Entity Framework, 2e, you might be familiar with the many extension methods that Julie created and combined to simplify retrieving instances of objects that are being tracked by the context from the ObjectStateManager. One simple property, DbSet.Local, now performs that same task. In fact, thanks to the new Change Tracker API, there’s no need to dig into the ObjectStateManager. It’s not even part of the DbContext API. Instead you can use DbContext.Entry or DbContext.Entries to find and even change the information being tracked by the context. You’ll learn more about these methods in Chapter 5.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required