Practical .NET

Looking at Entity Framework Core 1.0

There's more (and some less) in Entity Framework Core compared to Entity Framework 6, at least in version 1.0. While you can move to Entity Framework Core now, it might be too early for you.

Entity Framework Core (EFC) 1.0 is available for you to use in .NET Framework Core applications. It all works, but not all of the pieces are in place and some of the existing pieces have some rough edges. This means that, even if you start building a .NET Framework Core application, you may still want to work with some version of Entity Framework 6 (though I'm not sure why you'll need to).

With both technologies under development, specifying the differences between them is a moving target, but here's the situation at the time of this writing (November 2016) with EFC 1.1 scheduled for December or the first quarter of 2017.

Structure
There are structural and architectural differences between Entity Framework 6 (hereafter, EF6) and EFC. These reflect the main point of the move to .NET Framework Core: EFC is more lightweight than EF6, designed to be more extensible, and supports running in the .NET Framework Core runtime on platforms other than Windows. These differences become obvious as soon as you add EFC to your application: While EF6 is a single NuGet package, EFC currently requires you to add between two and five packages (Microsoft.EntityFrameworkCore.SqlServer and Microsoft.EntityFrameworkCore.Design just being the two essential packages required to work with Microsoft SQL Server).

The good news is that, those architectural issues aside, writing code with EFC looks very much like writing code with EF6 (though the EFC team describes moving an application from EF6 to EFC as "more of a port rather than an upgrade"). In practice, the architectural differences only occasionally show up in your code. For example, while creating an Entity object in EFC looks exactly like creating an Entity object in EF6, when you create a DbContext object in EFC, you'll need to override the DbContext OnConfiguring method to specify how the context is to be used. Typical code looks like this:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
  optionsBuilder.UseSqlServer(
    @"Data Source =.\SqlExpress; Initial Catalog = CustomerOrders; Integrated Security = True");
  base.OnConfiguring(optionsBuilder);
}

What's Missing
Probably the biggest piece of functionality that's actually missing in EFC is lazy loading. If you retrieve an entity object using the Include method to reference a navigation property then all of the child objects at the end of that navigation property will come over from the database with that entity object. If you don't use the Include statement, however, when you read that navigation property there will be nothing there. As I've suggested in other articles, I think lazy loading is a niche solution so this may not be a problem for you. Implementing lazy loading is included in the roadmap for EFC 2.0 (though EFC 1.1 has what's called "explicit loading").

Also not supported is connection resiliency. If you're in an environment where your connections are dodgy then this lack of support for retrying commands that are interrupted by breaks in the connection to the database may cause you to defer moving to EFC. I say "defer" and "yet" because this is also an issue that's to be addressed in EFC 1.1.

With EFC, you shouldn't be surprised if a LINQ statement that looks fine to you and would succeed in EF6 fails in EFC. You should still be able to perform your query, though -- the EFC team is confident that any LINQ query that does fail can be rewritten to deliver the same result in a way that EFC will accept. Some async queries will run but will be noticeably slower in EFC than they will in the current version of EF.

Not all inheritance mapping schemes are supported in EFC 1.0. This addresses what relational database designers called the supertype/subtype problem (for example, where you have a set of employees and some are paid hourly while some are on salary). With EFC 1.1 you have only one option: A single table holding all employees that's mapped to hourly and salary classes, plus a base class that holds information common to both types of employees. The other two options (separate tables for hourly and salary employees; separate tables for hourly and salary employees, plus one table for common information) aren't supported yet.

Some other issues: If you have a many-to-many relationship, you'll have to include an entity class that represents the join/intersection table in your model. The only option for calling stored procedures is to use the FromSql method (which is what most code-first developers were doing, anyway, but developers leveraging the visual designer will miss this). There's no support for seeding databases with information as part of a code-first programming strategy (again, as yet).

Tooling
Some of the tools that you take for granted with EF6 aren't (as yet) fully integrated with EFC. There are three essential tools that you'll need and they're all part of the Microsoft.EntityFrameworkCore.SqlServer.Design package.

For "database-first" development, you need Scaffold-DbContext. This tool generates .NET entity classes and DbContext objects from a connection string. There's no ability to update previously generated classes with changes from the database (again, something developers using the visual designer will miss). For "code-first" development, you need Add-Migration to initially generate your database and Update-Database to migrate changes from your classes to your tables. All of these tools must be run from the Package Manager Console -- there's no integration with the Visual Studio GUI yet.

I found that getting these tools installed can be finicky (though, to be fair, I've been working with preview versions). I had to back out the EFC-related packages I'd installed with the NuGet GUI and re-install using the Package Manager Console. I also had to install the preview version of Microsoft.Extensions.Logging. Only after those changes was I able to successfully install the package containing the tools.

Your Choices
With EFC 1.0 out the door, the Entity Framework team first refocused on EF6.2, but is working on both EFC and EF6 in parallel. While EF6 will, to quote the EFC team, see "bug fixes and minor improvements," the future belongs to EFC. For example, support for NoSQL databases is included in the Entity Framework Core roadmap, but is not part of the plans for EF6.

You won't really need to worry about EFC until you move to .NET Framework Core. If you asked my opinion I would say that, when that happens, you'll find that EFC will offer you everything you had in EF6, plus some additional cool stuff.

If you have to start developing with EFC right now you'll find some awkwardness and some missing features but, I suspect, nothing you can't work around. If you were creating a new application in .NET Framework Core, I would probably use EFC because that is, after all, where the future is. I would stick with EF 6 in a .NET Framework Core for Windows only if I had some compelling reason -- the limitations on inheritance mapping, the lack of speed on some async queries, the lowered support for stored procedures and (perhaps) having to include join/intersection table entities might fall into that category.

If you have to move an existing application to EFC … well, it will be neither pretty nor fun but it is doable. The most time-consuming issues will be tracking down places where missing functionality (for example, where you were counting on lazy loading or having a speedy async query) is causing your application to behave "differently." The most annoying issue will be inserting join/intersection tables for many-to-many relationships.

Or, in other words, it's all about what you'd expect at this point in the 1.0 version of a new Microsoft technology.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Compare New GitHub Copilot Free Plan for Visual Studio/VS Code to Paid Plans

    The free plan restricts the number of completions, chat requests and access to AI models, being suitable for occasional users and small projects.

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

Subscribe on YouTube