This site uses cookies for analytics, personalized content and ads. By continuing to browse this site, you agree to this use. Learn more
Microsoft Logo
Gray Pipe
  • Developer Network
    • Downloads
      • Visual Studio
      • SDKs
      • Trial software
    • Programs
      • Subscriptions
      • Students
      • ISV
      • Startups
      • Events
    • Community
      • Magazine
      • Forums
      • Blogs
      • Channel 9
    • Documentation
      • APIs and reference
      • Dev centers
      • Samples
      • Retired content
Developer Network Developer

Subscriber portal

Get tools
magazine
  • Issues and downloads
    • All issues
    • 2018
      • April 2018
      • March 2018
      • February 2018
      • January 2018
    • 2017
      • Connect(); 2017
      • December 2017
      • November 2017
      • October 2017
      • September 2017
      • August 2017
      • July 2017
      • June 2017
      • May 2017
      • April 2017
      • March 2017
      • February 2017
      • January 2017
    • 2016
      • December 2016
      • Connect(); 2016
      • November 2016
      • October 2016
      • September 2016
      • August 2016
      • July 2016
      • June 2016
      • May 2016
      • April 2016
      • March 2016
      • February 2016
      • January 2016
    • 2015
      • December 2015
      • November 2015
      • Windows 10 issue
      • October 2015
      • September 2015
      • August 2015
      • July 2015
      • June 2015
      • May 2015
      • April 2015
      • March 2015
      • February 2015
      • January 2015
    • 2014
      • Special 2014
      • December 2014
      • November 2014
      • October 2014
      • September 2014
      • August 2014
      • July 2014
      • June 2014
      • May 2014
      • April 2014
      • March 2014
      • February 2014
      • January 2014
    • 2013
      • Government 2013
      • December 2013
      • November 2013
      • October 2013
      • September 2013
      • August 2013
      • July 2013
      • June 2013
      • May 2013
      • April 2013
      • March 2013
      • February 2013
      • January 2013
    • 2012
      • December 2012
      • November 2012
      • Windows 8
      • October 2012
      • September 2012
      • August 2012
      • July 2012
      • June 2012
      • May 2012
      • April 2012
      • March 2012
      • February 2012
      • January 2012
    • 2011
      • December 2011
      • November 2011
      • October 2011
      • September 2011
      • August 2011
      • July 2011
      • June 2011
      • May 2011
      • April 2011
      • March 2011
      • February 2011
      • January 2011
    • 2010
      • December 2010
      • November 2010
      • October 2010
      • September 2010
      • August 2010
      • July 2010
      • June 2010
      • May 2010
      • April 2010
      • March 2010
      • February 2010
      • January 2010
    • 2009
      • December 2009
      • November 2009
      • October 2009
      • September 2009
      • August 2009
      • July 2009
      • June 2009
      • May 2009
      • April 2009
      • March 2009
      • February 2009
      • January 2009
  • Subscribe
  • Submit article
search clear
We’re sorry. The content you requested has been removed. You’ll be auto redirected in 1 second.
Issues and downloads 2013 March 2013 Data Points - Playing with the EF6 Alpha

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:

XML
Copy
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:

XML
Copy
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:

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

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

XML
Copy
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:

XML
Copy
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:

XML
Copy
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:

XML
Copy
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:

XML
Copy
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:

XML
Copy
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:

XML
Copy
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
XML
Copy
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:

XML
Copy
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

 

MSDN Magazine Blog

 

More MSDN Magazine Blog entries >


Current Issue


April 2018 issue

Browse All MSDN Magazines


Subscribe to MSDN Flash newsletter


Receive the MSDN Flash e-mail newsletter every other week, with news and information personalized to your interests and areas of focus.

Follow us
  • https://www.facebook.com/microsoftdeveloper
  • https://twitter.com/msdev
  • https://plus.google.com/111221966647232053570/
Sign up for the MSDN Newsletter
Is this page helpful?
Your feedback about this content is important.
Let us know what you think.
Additional feedback?
1500 characters remaining
Thank you!
We appreciate your feedback.

Dev centers

  • Windows
  • Office
  • Visual Studio
  • Microsoft Azure
  • More...

Learning resources

  • Microsoft Virtual Academy
  • Channel 9
  • MSDN Magazine

Community

  • Forums
  • Blogs
  • Codeplex

Support

  • Self support

Programs

  • BizSpark (for startups)
  • Microsoft Imagine (for students)
United States (English)
  • Newsletter
  • Privacy & cookies
  • Terms of use
  • Trademarks
logo © 2018 Microsoft