As part of Microsoft’s effort to modernize and make the .NET framework multi-platform, modular and open-source, a new lightweight and extensible version of Entity Framework, Entity Framework Core 1.0, has been released. Nate recently shared a post on how he used Entity Framework Core to rapidly prototype and test ASP.NET Core applications. So, we thought we’d share an overview of all the new stuff in EF Core!

Entity Framework is a Microsoft Object Relational Mapper (ORM) which allows .NET developers to forget about database complexity and work directly with domain-specific objects. This keeps developer focus on application logic rather than the complexities of where data is stored, how to retrieve data, and how to map database objects to domain entities.

Entity Framework Core is a new codebase and some of the features that were present on previous versions are not yet available. Most of the top-level APIs remain the same, so developers coming from Entity Framework 6.x will feel comfortable working with it. The source code is public on GitHub (previous versions were originally available in CodePlex).

Features Available in Entity Framework Core 1.0

EF Core, like ASP.NET Core, is cross-platform so applications written on these frameworks can run on Linux and Mac OS, not just Windows. Like its predecessor, Entity Framework Core is modular and can connect to a variety of database providers. Providers for SQL Server, SQLite, and Postgres are available today, with MySQL and others (like NoSQL) coming soon. There are community-built providers available on Github as well.

In-memory provider

Mocking and testing your data-access layer can be time-consuming and painful, but not anymore! EF Core comes with an in-memory provider, which helps to test applications without writing code to mock your database context. Using an in-memory data store, you can exercise your data access code against a real database that only exists in memory.

Lightweight, modular, and extensible

Following modern application framework philosophy, EF Core has been decomposed into smaller manageable packages/components and you can use only those that are useful to your project. These components can also be extended to add additional functionality.

To get started, simply install the packages for the providers you will use. For example, if you want to use the SQL Server provider, you can install it using the NuGet Package Manager:

Install-Package Microsoft.EntityFrameworkCore.SqlServer 1 2 Install - Package Microsoft . EntityFrameworkCore . SqlServer

Or we can edit the project.json file and add this line to the dependencies section:

"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0" 1 2 "Microsoft.EntityFrameworkCore.SqlServer" : "1.0.0"

Then (re)install all your dependencies either in Visual Studio or with the brand new .NET CLI using the restore command:

dotnet restore 1 2 dotnet restore

Shadow Properties

Shadow properties make it possible to add properties without affecting the domain model.

This is useful both to avoid contaminating the domain model and also when source code is not available to the developer. The values can be changed and maintained by the Change Tracker API. They can also participate in LINQ to Entity query, database migration, and Create/Update operation.

For example, you can define a LastUpdated shadow property on Course entity:

public class CoursesContext : DbContext { public DbSet<Course> Courses { get; set; } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Course>() .Property<DateTimeOffset>("LastUpdated"); } } 1 2 3 4 5 6 7 8 9 10 11 12 public class CoursesContext : DbContext { public DbSet < Course > Courses { get ; set ; } public DbSet < Student > Students { get ; set ; } protected override void OnModelCreating ( ModelBuilder modelBuilder ) { modelBuilder . Entity < Course > ( ) . Property < DateTimeOffset > ( "LastUpdated" ) ; } }

Setting the shadow property value:

context.Entry(myCourse).Property("LastUpdated").CurrentValue = DateTimeOffset.Now; 1 2 context . Entry ( myCourse ) . Property ( "LastUpdated" ) . CurrentValue = DateTimeOffset . Now ;

Reference it on LINQ queries:

var courses = context.Courses .OrderBy(c => EF.Property<DateTimeOffset>(c, "LastUpdated")); 1 2 3 var courses = context . Courses . OrderBy ( c = > EF . Property < DateTimeOffset > ( c , "LastUpdated" ) ) ;

Mixed client/server evaluation

When you write a query which involves client-side methods, EF Core is smart enough to identify which part of the query can run on the database and which part can only be run in-memory. Of course, this can lead to performance issues in some scenarios so this feature can easily be toggled off within your configuration.

In the following example, I defined a helper “GetDurationDetail” method which calculates the duration of a course in weeks and returns a string with this information.

var courses = context.Courses .Where(course => course.StartDate.Year == DateTimeOffset.Now.Year) .Select(course => new { Id = course.Id, Name = course.Name, Duration = GetDurationDetail(course.StartDate, course.EndDate); }) .ToList(); public static string GetDurationDetail(DateTimeOffset startDate, DateTimeOffset endDate) { var weeks = (endDate - startDate).Days / 7; var detail = String.Format("This course has a duration of {0} weeks", weeks); return detail; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var courses = context . Courses . Where ( course = > course . StartDate . Year == DateTimeOffset . Now . Year ) . Select ( course = > new { Id = course . Id , Name = course . Name , Duration = GetDurationDetail ( course . StartDate , course . EndDate ) ; } ) . ToList ( ) ; public static string GetDurationDetail ( DateTimeOffset startDate , DateTimeOffset endDate ) { var weeks = ( endDate - startDate ) . Days / 7 ; var detail = String . Format ( "This course has a duration of {0} weeks" , weeks ) ; return detail ; }

As the SQL provider has no idea how the helper method is implemented and how to translate it to SQL, it will be not evaluated in the database. However, the rest of the query is evaluated and once the data is returned to the client the StartDate and EndDate properties are passed to the method and performed on the client side.

As I mentioned above, this feature can lead to performance issues depending

on the amount of data, and how much of that data is filtered out, so be sure to pay attention to what is added into your queries.

var shortCourses = context.Courses .Where(course => GetDurationDetail(course.StartDate, course.EndDate).Contains("1 weeks")) .ToList(); 1 2 3 4 var shortCourses = context . Courses . Where ( course = > GetDurationDetail ( course . StartDate , course . EndDate ) . Contains ( "1 weeks" ) ) . ToList ( ) ;

In this scenario, the helper method is used in the Where clause as a filter, so all the data is pulled into memory and then the filter is applied on the client side. EF will log a warning when client evaluation is performed, but this can be changed to either throw an exception or do nothing by configuring your context in the OnConfiguring method.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying;Trusted_Connection=True;") .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); } 1 2 3 4 5 6 7 protected override void OnConfiguring ( DbContextOptionsBuilder optionsBuilder ) { optionsBuilder . UseSqlServer ( @ "Server=(localdb)\mssqllocaldb;Database=EFQuerying;Trusted_Connection=True;" ) . ConfigureWarnings ( warnings = > warnings . Throw ( RelationalEventId . QueryClientEvaluationWarning ) ) ; }

Bonus: Asynchronous LINQ Methods and SaveChanges

Entity Framework 6 introduced task-based asynchronous methods alongside the traditional methods methods that represent querying and update operations. Entity Framework Core continues this effort and includes native asynchronous LINQ and SaveChanges methods that you can use in your async methods. This means that the current thread will be released while waiting for the query to complete, allowing other requests to be processed while the database is working.

If you haven’t taken advantage of the asynchronous methods in EF6, migrating to Entity Framework Core is a great excuse to start!

Features Expected in Future Entity Framework Core Releases

There are several features from previous EF versions that are not yet implemented on EF Core 1.0. The most critical missing feature is the ability to use lazy loading on your entities. The only way to access related data in EF Core is to eagerly load it via the Include method. This has a big impact on the performance of your application because EF will query and load all the data on navigation properties as soon as the LINQ query is created, instead of querying it when they are accessed. This can be really dangerous on dense one-to-many relationships.

Also missing is a more efficient translation of queries with more logic evaluated in the database rather than in memory.

Updating a model from a database, which was previously reverse engineered from the database will be not available. Another visual miss will be the ability to see a graphical representation of the code-based model.

And last but not least, we’re still missing filtered loading to allow a subset of related entities to be loaded and many-to-many relationships without join entities, which means that you will need to create an entity class to represent the join table and map the two separate one-to-many relationships.

Next Steps

In this article, we have reviewed new and pending EF Core 1.0.0 features. This is by no means the complete list of all new features. To learn more about what’s new in EF Core 1.0.0 check next resources:

Or, dive into authentication with .NET and Stormpath: