March 2013

Volume 28 Number 03

Data Points - Playing with the EF6 Alpha

By Julie Lerman | March 2013

Julie LermanThere’s nothing like a shiny new toy to play with, and although it’s possible to download nightly builds of Entity Framework 6 (EF6) as it evolves, I waited for the first packaged alpha release (which came on Oct. 30, 2012) to dig in and start playing.

If you’re asking yourself, “Huh? Nightly builds?” you might have missed the news that after the EF5 release, Entity Framework became an open source project and subsequent versions are being openly (and communally) developed at entityframework.codeplex.com. I recently wrote a blog post, “Making your way around the Open Source Entity Framework CodePlex Site” (bit.ly/W9eqZS), which I recommend checking out before heading over to those CodePlex pages.

The new version will go a long way toward making EF more flexible and extensible. In my opinion, the three most important features coming to EF in version 6 are:

  1. Stored procedure and function support for Code First
  2. Support for the .NET 4.5 Async/Await pattern
  3. The core Entity Framework APIs that currently live inside the Microsoft .NET Framework

Not only does this last point enable enum and spatial type support for apps that target the .NET Framework 4, but because EF is open source it also means that all of EF now benefits from being open source.

Though it might not have the broad appeal of these three features, there’s a lot of other significant functionality on its way as well. For example:

  • The custom Code First conventions that got pulled prior to the release of EF4.1 are now in EF6, with a variety of ways to implement.
  • Code First migrations support multiple database schemas.
  • You can define Entity Framework configurations in code rather than setting them in a web.config or app.config file (which can be complicated).
  • The code-based configuration is possible because of new support for extensibility with dependency resolvers.
  • You can customize how Code First creates the _Migrations­History table so that it’s more amenable to a variety of database providers.
  • The EF Power Tools are being enhanced and added into the Visual Studio EF Designer. One enhancement will provide a nicer path for choosing a model workflow, including Code First.

Getting EF6 Alpha

Hard-core devs might be interested in downloading the nightly builds. If you prefer to use the released packages, you can have a smooth install experience by grabbing the NuGet Package. Use the NuGet Package Manager and select “Include Prerelease” to get the EF6 package. If you install from the Package Manager Console, be sure to add “-prerelease” to the end of your install-package command.

Note that the Dec. 10, 2012, release that I’m exploring (with file version 6.0.11025.0 and product version 6.0.0-alpha2-11210) doesn’t include the stored procedure or function support, or the tooling consolidation. Also, as this is such an early alpha, I anticipate some of the details for these features will change with new releases. While the overall concepts will remain, some of the syntax or other details are likely to evolve based on feedback from the community. Thanks to the exercise of working on this column, I was able to provide some feedback myself.

.NET 4.5 Async in EF6

Leveraging asynchronous processing in the .NET Framework to avoid blocking when it’s waiting for data to be returned has daunted many a developer, especially when using disconnected apps or remote databases. The Background Worker process arrived in the .NET Framework 2.0, but it was still complex. ADO.NET 2.0 helped a bit with methods like BeginExecuteQuery and EndExecuteQuery, but Entity Framework has never had anything like these. One of the major additions to the .NET Framework 4.5 is the new Asynchronous pattern, which has the ability to wait for results from methods that have been defined as Asynchronous, dramatically simplifying Async processing.

In EF6, a slew of methods have been added that support the .NET 4.5 Asynchronous pattern. Following the guidelines for the new pattern, the new methods all have Async appended to their names, such as  SaveChangesAsync, FindAsync and Execute­SqlCommandAsync. For LINQ to Entities, a new namespace called System.Data.Entity.IQueryableExtensions contains Async versions of the many LINQ methods, including ToListAsync, First­Or­DefaultAsync, MaxAsync and SumAsync. And to explicitly load data from entities managed by a DbContext, LoadAsync is now available.

What follows is a little experiment I’ve conducted with this feature, first without using the Asynchronous methods and then with them. I do highly recommend reading up on the new Async pattern. “Asynchronous Programming with Async and Await (C# and Visual Basic),” available at bit.ly/U8FzhP, is a good starting point.

My example contains a Casino class that includes a rating for the casino. I’ve created a repository method that will find a given casino, increment its rating using my UpdateRating method (which is inconsequential for this explanation, and therefore not listed) and save the change back to the database:

public void IncrementCasinoRating(int id)
{
  using (var context = new CasinoSlotsModel())
  {
    var casino =  context.Casinos.Find(id);
    UpdateRating(casino);
    context.SaveChanges();
  }
}

There are two points in this method where a thread can get blocked. The first is when calling Find, which causes the context to search its in-memory cache for the requested casino and query the database if it’s not found. The second is when asking the context to save the modified data back to the database.

I’ve structured my UI code solely to demonstrate the relevant behavior. The UI includes a method that calls the repository’s IncrementCasinoRating and, when it’s finished, writes out a notification in the console:

private static void UI_RequestIncrement (SimpleRepository repo)
{
  repo.IncrementCasinoRating(1);
  Console.WriteLine("Synchronous Finish ");
}

In another method, I trigger the test by calling UI_ Increment­CasinoRating and follow that with another notification:

UI_RequestIncrement (repo);
Console.WriteLine(" After sync call");

When I run this, I’ll see the following in the console output:

Synchronous Finish
After sync call

That’s because everything stopped while waiting for each of the steps in IncrementCasinoRating to complete—finding the casino, updating the rating and saving to the database.

Now I’ll change the repository method so that it uses the new FindAsync and SaveChangesAsync methods. Following the Asynchronous pattern, I also need to make the method asynchronous by:

  • adding the async keyword to its signature
  • appending Async to the method name
  • returning a Task; if the method returns results, then you would return Task<resulttype>

Within the method, I call the new Async methods—FindAsync and SaveChangesAsync—as prescribed, using the await keyword:

public async Task IncrementCasinoRatingAsync(int id)
{
  using (var context = new CasinoSlotsModel())
  {
    var casino=await context.Casinos.FindAsync(id);
    // Rest is delayed until await has received results
    UpdateRating(casino);
    await context.SaveChangesAsync();
    // Method completion is delayed until await has received results
  }
}

Because the method is marked async, as soon as the first await is hit, the method returns control to the calling process. But I’ll need to modify that calling method. There’s a waterfall path when building behavior for the Asynchronous pattern, so not only does the method make a special call to my new Asynchronous method, it also needs to be Asynchronous itself because it’s being called by yet another process:

private static async void UI_RequestIncrementAsync(
  SimpleRepository repo)
{
  await repo.IncrementCasinoRatingAsync(1);
  // Rest is delayed until await has received results
  Console.WriteLine(" Asynchronous Finish ");
}

Notice that I’m using await to call the repository method. That lets the caller know this is an Asynchronous method. As soon as that await is hit, control will be returned to the caller. I’ve also modified the startup code:

UI_RequestIncrementAsync(repo);
  Console.WriteLine(" After asynchronous call");

Now when I run this code, the UI_RequestIncrementAsync method returns control to the caller as it’s also calling the repository method. That means I’ll immediately get to the next line of startup code, which prints out “After asynchronous call.” When the repository method finishes saving to the database, it returns a Task to the method that called it, UI_RequestIncrementAsync, which then executes the rest of its code, printing out a message to the console:

After asynchronous call
Asynchronous Finish

So my UI was able to finish without waiting for EF to complete its work. If the repository method had returned results, they would have bubbled up in the Task when they were ready.

This little exercise helped me see the new Asynchronous methods in action. Whether you’re writing client-side or disconnected applications that rely on asynchronous processing, it’s a great benefit that EF6 now supports the new Asynchronous pattern with such simplicity.

Custom Conventions

Code First has a set of built-in conventions that drive its default behavior when it builds a model along with database mappings from your classes. You can override those conventions with explicit configurations using DataAnnotations or the Fluent API. In the early betas of Code First you could also define your own conventions—for example, a convention that sets all strings to map to database fields with a max length of 50. Unfortunately, the team wasn’t able to get this feature to a satisfactory state without holding up Code First, so it didn’t make it into the final release. It has now made its return in EF6.

There are several ways to define your own conventions.

Using a lightweight convention is the simplest method. It allows you to specify conventions fluently in the OnModelCreating overload of the DbContext. Lightweight conventions are applied to your classes and are limited to configuring properties that have a direct correlation in the database, such as length to MaxLength. Here’s an example of a class that has no special configurations and therefore, by default, its two string fields would map to nvarchar(max) data types in a SQL Server database:

public class Hotel
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
  }

I’ve added a lightweight convention in the model specifying that the API should check the properties of any entity it’s processing and set the MaxLength of strings to 50:

modelBuilder.Properties<string>()
  .Configure(p => p.HasColumnType("nvarchar"));

You can see in Figure 1 that Code First ensured the Name and Description fields do have a max length of 50.

A Custom Convention Made the Max Length of These nvarchars 50
Figure 1 A Custom Convention Made the Max Length of These nvarchars 50

You can also define a convention by implementing an existing interface, such as the convention interface for handling DateTime properties—the DateTimePropertyConfiguration class in the System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive namespace. Figure 2 shows an example in which I forced DateTime properties to map to the SQL Server date type instead of the default datetime. Note that this sample follows Microsoft guidance—I won’t apply my configuration if the attribute (ColumnType in this case) has already been configured.

Figure 2 Mapping DateTime Properties to the SQL Server Date Type

public  class DateTimeColumnTypeConvention :
  IConfigurationConvention<PropertyInfo, DateTimePropertyConfiguration>
  {
    public void Apply(
      PropertyInfo propertyInfo,
      Func<DateTimePropertyConfiguration> configuration)
    {
      // If ColumnType hasn't been configured ...
      if (configuration().ColumnType == null)
      {
        configuration().ColumnType = "date";
      }
    }
  }

Conventions have a specific pecking order, which is why you have to be sure that the column type hasn’t already been configured before applying the new ColumnType.

The model builder needs to know how to find this new convention. Here’s how to do that, again in the OnModelCreating overload method:

modelBuilder.Conventions.Add(new DateTimeColumnTypeConvention());

There are two other ways to customize conventions. One method allows you to create custom attributes you can use in your classes as easily as DataAnnotations. The other is more granular: rather than building a convention that depends on what the ModelBuilder learns from your classes, this method allows you to affect the metadata directly. You’ll find examples of all four styles of custom conventions in the MSDN Data Developer Center documentation, “Custom Code First Conventions” (msdn.microsoft.com/data/jj819164). As EF6 evolves, this document will either gain a link to a more-current version or be modified to align with the most-recent version.

Multiple Schema Support for Migrations

EF6 gives Code First migrations the ability to handle multiple schemas in databases. For more about this feature, take a look at the detailed blog post I wrote shortly after the alpha was released: “Digging in to Multi-Tenant Migrations with EF6 Alpha” (bit.ly/Rrz1MD). Do keep in mind, however, that the name of the feature has changed from “Multi-Tenant Migrations” to “Multiple Contexts per Database.”

Code-Based Configurations

You can already specify database-relevant configurations for Entity Framework in application config files (app.config and web.config), freeing you from having to supply the configurations at application startup or in the constructor of the context. Now, in EF6, it’s possible to create a class that inherits from a new DbConfiguration class where you can specify details such as the default database provider for Code First, the database-initialization strategy (for example, DropCreateDatabaseIfModelChanges) and others. You can create this DbConfiguration class in the same project as your context or in a separate project, allowing multiple contexts to benefit from a single configuration class. The code-based configuration overview at msdn.microsoft.com/data/jj680699 provides examples of the various options.

Core EF Is Now in EF6 and It’s Open Source, Too

While the Code First and DbContext APIs have always been disconnected from the .NET release cycle, the core of EF has been embedded in the .NET Framework. This is the core functionality—the ObjectContext API, querying, change-tracking, the Entity­Client provider and so much more. This is why support for enums and spatial data had to wait for the .NET Framework 4.5 to be released—those changes had to be made deep within the core APIs.

With EF6, all of those core APIs have been pulled into the open source project and will be deployed via the NuGet package. It’s interesting to see the EF5 and EF6 namespaces side-by-side, as shown in Figure 3. As you can see, in EF6 there are many more namespaces.

EF6 Has Acquired the Namespaces of the EF Core APIs from the .NET Framework
Figure 3 EF6 Has Acquired the Namespaces of the EF Core APIs from the .NET Framework

Enum and Spatial Support for .NET 4 Apps

As I mentioned earlier, one of the great benefits of having the core APIs inside of EF6 is that it removes some of the dependency on .NET versions for EF-specific features—most notably the enum and spatial data support added to EF in the .NET Framework 4.5. Existing apps that targeted the .NET Framework 4 with EF were not able to take advantage of this with EF5. Now that limitation is gone because EF6 includes the enum and spatial support, and the features are therefore no longer dependent on the .NET Framework. The existing documentation on these features can help you use them in apps that target the .NET Framework 4.

Help Drive the Evolution of EF

With Entity Framework now an open source project, developers can help themselves and others by getting involved with its design and development. You can share your thoughts, comments and feedback, whether from reading the specs, taking part in discussions and issues, playing with the latest NuGet package, or grabbing nightly builds and banging on them. You can also contribute code, either for one of the issues listed on the site that nobody’s working on yet or something of your own that you can’t live without in EF.


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) as well as a Code First edition (2011) and a DbContext edition (2012), all from O’Reilly Media. Follow her on Twitter at twitter.com/julielerman.

Thanks to the following technical expert for reviewing this article: Glenn Condron