March 2012

Volume 27 Number 03

Data Points - Entity Framework Code First and DbContext FAQs

By Julie Lerman | March 2012

Julie LermanThis month, I’d like to share the answers to questions I’m frequently asked about Code First and DbContext in Entity Framework 4.2. To maximize space, I’ll point to additional resources where you can find detailed information to supplement the material I provide.

Will Code First and DbContext Be Added to the .NET Framework?

No. Code First and DbContext will be distributed separately from the Microsoft .NET Framework release cycle, allowing the Entity Framework team to release updates when they’re ready without waiting for the next official release of the .NET Framework. Code First and the DbContext API are part of the EntityFramework.dll assembly, which you can add to your projects dynamically using NuGet. Installing the NuGet extension in Visual Studio gives you the Library Package Manager, which lets you add a reference to EntityFramework.dll to your project. Figure 1 shows the EntityFramework package (currently the most popular download in the NuGet package library) in the Visual Studio Library Package Manager.

Installing Code First and DbContext into a Project via EntityFramework.dll
Figure 1 Installing Code First and DbContext into a Project via EntityFramework.dll

You can read more about the team’s plans for releasing features of Entity Framework and why they decided to focus on using NuGet for deploying certain types of features outside of the .NET APIs in their October 2011 blog post, “How We Talk About EF and Its Future Versions” (bit.ly/owoWgn).

No. The Include method allows you to eagerly load related data when executing queries against an Entity Data Model. Unfortunately, you can retrieve only complete sets of related data with eager loading. This is also true for lazy loading and, in all but one case, for explicit loading. That single case: When you explicitly load through the change tracker API, you can apply a Query method followed by a Where filter:

context.Entry(personInstance)
  .Collection(p => p.Aliases)
  .Query()
  .Where(a=>a.FirstName == "Natasha")
  .Load();

But to be clear, you can’t do this for eager loading with Include.

This is how Include has worked since the first release of Entity Framework in the .NET Framework 3.5. If you want to combine eager loading with filtering, consider using projections. You can read more about this in the June 2011 Data Points column, “Demystifying Entity Framework Strategies: Loading Related Data,” at msdn.microsoft.com/magazine/hh205756. I’ve also written a blog post on the topic, “Use Projections and a Repository to Fake a Filtered Eager Load,” at bit.ly/uZdnxy.

How Can I Use Lambdas with Include?

With the ObjectContext, the only way to use Include is by passing in a string to represent the navigation property to be eagerly loaded. For example, if you have a class of Road that has a property, Trees, which is an ICollection<Tree>, you would query for Roads with their Trees like this:

context.Roads.Include("Trees")

Many developers have created their own extension methods to allow them to use a strongly typed expression instead:

context.Roads.Include(r => r.Trees)

The ability to use lambda expressions with Include is now built into the DbContext API. You’ll find an example in Part 6 of Arthur Vickers’ wonderful 12-part blog series about the DbContext API (bit.ly/wgI5zW). Your attempts to use this feature might have been unsuccessful, however—as were mine. I had to put my ego aside and ask someone on the team how to get the lambda support. It turns out that in addition to a reference to EntityFramework.dll, you need a using directive (or Imports for Visual Basic) for System.Data.Entity in the code file where you’re attempting to use Include with a lambda. If you want to expand the eager loading on a collection to multiple levels of relationships using the lambdas, you have to incorporate extra Select methods. For example, if your Tree class has an ICollection<Leaf> and you want to eager load the leaves along with the trees, the string representation would look like this:

context.Roads.Include("Trees.Leaves")

However, the lambda relies on additional logic to provide the next level of the relationship. Here’s the syntax you’d use to select roads along with the trees and their leaves:

context.Roads.Include(r => r.Trees.Select(t => t.Leaves))

I can’t talk about using multiple levels of Include without adding a reminder that the more relationships you attempt to eager load with Include, the more complex and degraded your SQL query could become. I always highly recommend profiling the SQL generated by Entity Framework (EF). In fact, the December 2010 Data Points column demonstrates various ways to profile the database when using EF.

I was surprised to learn that if you’re using the ObjectContext API, a reference to EntityFramework.dll plus a System.Data.Entity using directive will let you use lambdas with Include here, as well.

Do I Have to Wait for the .NET Framework 4.5 If I Want to Use Code First with WCF Data Services?

There are two assemblies for creating and consuming WCF Data Services in the .NET Framework 4: System.Data.Services.dll and System.Data.Services.Client.dll. If you try to use these with a DbContext and Code First classes, they won’t work out of the box. The issue is with DbContext, not Code First. DbContext didn’t exist when those assemblies were built, so they don’t understand it. In March 2011, Microsoft released a Community Technology Preview (CTP) that contained fixed-up assemblies (Microsoft.Data.Services.dll and Microsoft.Data.Services.Client.dll) that know how to work with the DbContext. So all you have to do is replace the default assemblies with these new assemblies and, in your data services, specify DataServiceProtocolVersion as V3 rather than V2. Here’s an example of what a simple data service might look like exposing a context (PersonModelContext) that inherits from DbContext:

public class DataService : DataService<PersonModelContext>
  {
    public static void InitializeService(DataServiceConfiguration config)
    {
      config.SetEntitySetAccessRule("People", EntitySetRights.All);
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }
}

The problem with this solution is that the new assemblies are only CTPs and not for production purposes. You’ll have to wait for the next Released to Manufacturing (RTM) release of Data Services to be able to use them in production.

But it’s possible to use a DbContext with .NET Framework 4 System.Data.Services assemblies. The CTP assemblies exist just to help you avoid writing extra code. All you need to do is access the underlying ObjectContext that supports the DbContext and provide that to the service. In July 2010, Rowan Miller, a key player at Microsoft behind Code First, demonstrated this in a blog post, “EF CTP4 Tips & Tricks: WCF Data Service on DbContext” (bit.ly/c2EA0l). That blog was written for an early preview of the DbContext, so I’ve updated his example to work with the version of DbContext class in Entity Framework 4.2 using PersonModelContext, a simple model that exposes one DbSet for a Person class. The context and class are shown in Figure 2.

Figure 2 Simple DbContext and Class Used by a Data Service

public class PersonModelContext : DbContext
{
  public DbSet<Person> People { get; set; }
}
public class Person
{
  public int PersonId { get; set; }
  [MaxLength(10)]
  public string IdentityCardNumber { get; set; }
  public string FirstName { get; set; }
  [Required]
  public string LastName { get; set; }
}

The data service is then defined to work with an ObjectContext, rather than specifically for the PersonModelContext that derives from DbContext. Then, by overriding the data service CreateData­Source method, you can expose the ObjectContext that underlies the PersonModelContext, thereby providing the needed ObjectContext to the service, as shown in Figure 3.

Figure 3 A WCF Data Service that Uses a DbContext with .NET Framework 4 Service APIs

public class DataService : DataService<ObjectContext>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("People", EntitySetRights.All);
    config.DataServiceBehavior.MaxProtocolVersion =
      DataServiceProtocolVersion.V2;
  }
  protected override ObjectContext CreateDataSource()
  {
    var dbContext = new PersonModelContext();
    var oContext = ((IObjectContextAdapter)dbContext).ObjectContext;
    return oContext;
  }
}

Because I want to focus on providing the ObjectContext, this is a simplified view of the code you might have in WCF Data Services.

The downside to this approach is that you won’t be able to use DbContext features such as Validation (as described in my December 2011 Data Points column, “Handling Entity Framework Validations in WCF Data Services,” at msdn.microsoft.com/magazine/hh580732) because the service is designed to work with an ObjectContext.

Should I Use Data Annotations or the Fluent API for Code First Configurations?

I get asked this question a lot. To understand the answer, it’s helpful to first understand the high-level differences between these two options.

Code First extends the Data Annotations that are already part of the .NET Framework 4 System.ComponentModel.DataAnnotations namespace. In addition to annotations such as ValidationAttributes (Required, StringLength, RegEx), Entity Framework adds attributes to specify database mappings (for example, Column, Table and Timestamp) or other model-specific features such as ComplexType. Annotations are simple to apply in a class, as the Person class in Figure 2 demonstrates.

There are some possible drawbacks to using Data Annotations to configure your classes for Code First. One is that you might not be a fan of adding persistence-related logic to your business classes. If you’ve asked yourself, “What does the name of a database column have to do with my domain model?” you might not want to use the Data Annotations. Another is that these mappings require you to reference EntityFramework.dll from assemblies that contain your business classes. (This changes as of the .NET Framework 4.5, which will take ownership of the EF-related Data Annotations.) That, too, might not be something you wish to do, especially if you’re distributing your application across tiers. Moreover, the Code First Data Annotations don’t expose the complete lineup of configurations that can be applied using Code First. Some configurations, for example those specifying particular details for a Table Per Hierarchy (TPH) mapping, can be achieved only using the Fluent API.

My recommendation to developers is to pick the style you like. If you prefer to have your configurations expressed by the Entity Framework DbContext, then use the Fluent API. If you like the simplicity of applying attributes and don’t mind having the Code First mapping logic in your classes, use Data Annotations. If you’ve chosen to use Data Annotations and come across a configuration that can be expressed only with the Fluent API, then add that configuration fluently and use a combination of Data Annotations and Fluent configurations.

Can I Use Code First with an Existing Database?

Absolutely! Although the default behavior for Code First is to (helpfully) create a database for you, you can point to an existing database with your own connection string and have Code First use that. There are some internal features of Code First that let you programmatically specify the database as well. For example, you can overload the DbContext constructor with a database name or a database connection string. You can also specify and even customize DbContext ConnectionFactory types (such as SqlConnectionFactory).

You’ll need to ensure that Code First conventions plus any configurations you’ve added accurately represent how your classes will map to the existing database. Microsoft has been working on a tool that can reverse-engineer a database into classes plus Code First fluent configurations, which can provide a great head start. You can learn more about this tool in my May 2011 blog post, “Quick Look at Reverse Engineer DB into Code First Classes” (bit.ly/lHJ2Or).

When specifying the location, avoid the schema validation and database initialization that DbContext does by default with Code First. You can completely disable this feature via Code First database initialization:

Database.SetInitializer<MyContext>(null)

You’ll find more on this topic in the MSDN Data Developer Center article and video, “Database Initializers in Entity Framework 4.1” (msdn.microsoft.com/data/hh272552). For detailed examples of working with the ConnectionFactory classes and DbContext overloads, be sure to check out “Programming Entity Framework: Code First” (O’Reilly Media, 2011), a book I coauthored with Rowan Miller from the Code First team.

Additional Resources

There are many places to learn about working with Code First and DbContext. The Entity Framework team blog at blogs.msdn.com/adonet is filled with walk-throughs and examples. Some team member blogs, such as Rowan Miller’s (romiller.com) and Arthur Vickers’ (blog.oneunicorn.com/author/ajcvickers), are great places to read about advanced techniques. The MSDN forums and StackOverflow.com continue to be great places to read threads or ask your own questions. Miller and I recently wrote two short books, the aforementioned “Programming Entity Framework: Code First” and “Programming Entity Framework: DbContext” (O’Reilly Media, 2012). You can get these in print or digital format.

There’s no need to struggle with trying to figure things out on your own.


Julie Lerman is a Microsoft MVP, .NET mentor and consultant who lives in the hills of Vermont. You can find her presenting on data access and other Microsoft .NET topics at user groups and conferences around the world. She blogs at thedatafarm.com/blog and is the author of “Programming Entity Framework” (2010) and “Programming Entity Framework: Code First” (2011), both from O’Reilly Media. Follow her on Twitter at twitter.com/julielerman.

Thanks to the following technical experts for reviewing this article: Mike Flasko and Diego Vega