February 17th, 2021

Announcing Entity Framework Core 6.0 Preview 1

Jeremy Likness
Principal Program Manager - .NET Web Frameworks

Today, the Entity Framework Core team announces the first preview release of EF Core 6.0. This release includes new attributes, built-in functions, and database-specific improvements to SQLite and SQL Server capabilities.

Prerequisites

  • EF Core 6.0 currently targets .NET 5. This will likely be updated to .NET 6 as we near the release. EF Core 6.0 does not target any .NET Standard version; for more information see the future of .NET Standard.
  • EF Core 6.0 will not run on .NET Framework.

How to get EF Core 6.0 previews

EF Core is distributed exclusively as a set of NuGet packages. For example, to add the SQL Server provider to your project, you can use the following command using the dotnet tool:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 6.0.0-preview.1.21102.2

This following table links to the preview 1 versions of the EF Core packages and describes what they are used for.

Package Purpose
Microsoft.EntityFrameworkCore The main EF Core package that is independent of specific database providers
Microsoft.EntityFrameworkCore.SqlServer Database provider for Microsoft SQL Server and SQL Azure
Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite SQL Server support for spatial types
Microsoft.EntityFrameworkCore.Sqlite Database provider for SQLite that includes the native binary for the database engine
Microsoft.EntityFrameworkCore.Sqlite.Core Database provider for SQLite without a packaged native binary
Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite SQLite support for spatial types
Microsoft.EntityFrameworkCore.Cosmos Database provider for Azure Cosmos DB
Microsoft.EntityFrameworkCore.InMemory The in-memory database provider
Microsoft.EntityFrameworkCore.Tools EF Core PowerShell commands for the Visual Studio Package Manager Console; use this to integrate tools like scaffolding and migrations with Visual Studio
Microsoft.EntityFrameworkCore.Design Shared design-time components for EF Core tools
Microsoft.EntityFrameworkCore.Proxies Lazy-loading and change-tracking proxies
Microsoft.EntityFrameworkCore.Abstractions Decoupled EF Core abstractions; use this for features like extended data annotations defined by EF Core
Microsoft.EntityFrameworkCore.Relational Shared EF Core components for relational database providers
Microsoft.EntityFrameworkCore.Analyzers C# analyzers for EF Core

We also published the 6.0 preview 1 release of the Microsoft.Data.Sqlite.Core provider for ADO.NET.

Installing the EF Core Command Line Interface (CLI)

As with EF Core 3.0 and 3.1, the EF Core CLI is no longer included in the .NET Core SDK. Before you can execute EF Core migration or scaffolding commands, you’ll have to install this package as either a global or local tool.

To install the preview tool globally, first uninstall any existing version with:

dotnet tool uninstall --global dotnet-ef

Then install with:

dotnet tool install --global dotnet-ef --version 6.0.0-preview.1.21102.2

It’s possible to use this new version of the EF Core CLI with projects that use older versions of the EF Core runtime.


What’s New in EF Core 6 Preview 1

We maintain documentation covering new features introduced into each preview.

Some of the highlights from preview 1 are called out below. This preview also includes several bug fixes.

TIP You can run and debug into all the preview 1 samples shown below by downloading the sample code from GitHub.

UnicodeAttribute

GitHub Issue: #19794. This feature was contributed by @RaymondHuy.

Starting with EF Core 6.0, a string property can now be mapped to a non-Unicode column using a mapping attribute without specifying the database type directly. For example, consider a Book entity type with a property for the International Standard Book Number (ISBN) in the form “ISBN 978-3-16-148410-0”:

    public class Book
    {
        public int Id { get; set; }
        public string Title { get; set; }

        [Unicode(false)]
        [MaxLength(22)]
        public string Isbn { get; set; }
    }

Since ISBNs cannot contain any non-unicode characters, the Unicode attribute will cause a non-Unicode string type to be used. In addition, MaxLength is used to limit the size of the database column. For example, when using SQL Server, this results in a database column of varchar(22):

CREATE TABLE [Book] (
    [Id] int NOT NULL IDENTITY,
    [Title] nvarchar(max) NULL,
    [Isbn] varchar(22) NULL,
    CONSTRAINT [PK_Book] PRIMARY KEY ([Id]));

NOTE EF Core maps string properties to Unicode columns by default. UnicodeAttribute is ignored when the database system supports only Unicode types.

PrecisionAttribute

GitHub Issue: #17914. This feature was contributed by @RaymondHuy.

The precision and scale of a database column can now be configured using mapping attributes without specifying the database type directly. For example, consider a Product entity type with a decimal Price property:

    public class Product
    {
        public int Id { get; set; }

        [Precision(precision: 10, scale: 2)]
        public decimal Price { get; set; }
    }

EF Core will map this property to a database column with precision 10 and scale 2. For example, on SQL Server:

CREATE TABLE [Product] (
    [Id] int NOT NULL IDENTITY,
    [Price] decimal(10,2) NOT NULL,
    CONSTRAINT [PK_Product] PRIMARY KEY ([Id]));

EntityTypeConfigurationAttribute

GitHub Issue: #23163. This feature was contributed by @KaloyanIT.

IEntityTypeConfiguration instances allow ModelBuilder configuration for a each entity type to be contained in its own configuration class. For example:

public class BookConfiguration : IEntityTypeConfiguration<Book>
{
    public void Configure(EntityTypeBuilder<Book> builder)
    {
        builder
            .Property(e => e.Isbn)
            .IsUnicode(false)
            .HasMaxLength(22);
    }
}

Normally, this configuration class must be instantiated and called into from OnModelCreating. For example:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    new BookConfiguration().Configure(modelBuilder.Entity<Book>());
}

Starting with EF Core 6.0, an EntityTypeConfigurationAttribute can be placed on the entity type such that EF Core can find and use appropriate configuration. For example:

[EntityTypeConfiguration(typeof(BookConfiguration))]
public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Isbn { get; set; }
}

This attribute means that EF Core will use the specified IEntityTypeConfiguration implementation whenever the Book entity type is included in a model. The entity type is included in a model using one of the normal mechanisms. For example, by creating a DbSet property for the entity type:

public class BooksContext : DbContext
{
    public DbSet<Book> Books { get; set; }

    //...

Or by registering it in OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Book>();
}

NOTE EntityTypeConfigurationAttribute types will not be automatically discovered in an assembly. Entity types must be added to the model before the attribute will be discovered on that entity type.

Translate ToString on SQLite

GitHub Issue: #17223. This feature was contributed by @ralmsdeveloper.

Calls to ToString are now translated to SQL when using the SQLite database provider. This can be useful for text searches involving non-string columns. For example, consider a User entity type that stores phone numbers as numeric values:

    public class User
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public long PhoneNumber { get; set; }
    }

ToString can be used to convert the number to a string in the database. We can then use this string with a function such as LIKE to find numbers that match a pattern. For example, to find all numbers containing 555:

var users = context.Users.Where(u => EF.Functions.Like(u.PhoneNumber.ToString(), "%555%")).ToList();

This translates to the following SQL when using a SQLite database:

SELECT COUNT(*)
FROM "Users" AS "u"
WHERE CAST("u"."PhoneNumber" AS TEXT) LIKE '%555%'

Note that translation of ToString for SQL Server is already supported in EF Core 5.0, and may also be supported by other database providers.

EF.Functions.Random

GitHub Issue: #16141. This feature was contributed by @RaymondHuy.

EF.Functions.Random maps to a database function returning a pseudo-random number between 0 and 1 exclusive. Translations have been implemented in the EF Core repo for SQL Server, SQLite, and Cosmos. For example, consider a User entity type with a Popularity property:

    public class User
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public int Popularity { get; set; }
    }

Popularity can have values from 1 to 5 inclusive. Using EF.Functions.Random we can write a query to return all users with a randomly chosen popularity:

var users = context.Users.Where(u => u.Popularity == (int)(EF.Functions.Random() * 5.0) + 1).ToList();

This translates to the following SQL when using a SQL Server database:

SELECT [u].[Id], [u].[Popularity], [u].[Username]
FROM [Users] AS [u]
WHERE [u].[Popularity] = (CAST((RAND() * 5.0E0) AS int) + 1)

Support for SQL Server sparse columns

GitHub Issue: #8023.

SQL Server sparse columns are ordinary columns that are optimized to store null values. This can be useful when using TPH inheritance mapping where properties of a rarely used subtype will result in null column values for most rows in the table. For example, consider a ForumModerator class that extends from ForumUser:

    public class ForumUser
    {
        public int Id { get; set; }
        public string Username { get; set; }
    }

    public class ForumModerator : ForumUser
    {
        public string ForumName { get; set; }
    }

There may be millions of users, with only a handful of these being moderators. This means mapping the ForumName as sparse might make sense here. This can now be configured using IsSparse in OnModelCreating. For example:

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder
                .Entity<ForumModerator>()
                .Property(e => e.ForumName)
                .IsSparse();
        }

EF Core migrations will then mark the column as sparse. For example:

CREATE TABLE [ForumUser] (
    [Id] int NOT NULL IDENTITY,
    [Username] nvarchar(max) NULL,
    [Discriminator] nvarchar(max) NOT NULL,
    [ForumName] nvarchar(max) SPARSE NULL,
    CONSTRAINT [PK_ForumUser] PRIMARY KEY ([Id]));

NOTE Sparse columns have limitations. Make sure to read the SQL Server sparse columns documentation to ensure that sparse columns are the right choice for your scenario.

In-memory database: validate required properties are not null

GitHub Issue: #10613. This feature was contributed by @fagnercarvalho.

The EF Core in-memory database will now throw an exception if an attempt is made to save a null value for a property marked as required. For example, consider a User type with a required Username property:

    public class User
    {
        public int Id { get; set; }

        [Required]
        public string Username { get; set; }
    }

Attempting to save an entity with a null Username will result in the following exception:

Microsoft.EntityFrameworkCore.DbUpdateException: Required properties ‘{‘Username’}’ are missing for the instance of entity type ‘User’ with the key value ‘{Id: 1}’.

This validation can be disabled if necessary. For example:

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .LogTo(Console.WriteLine, new[] { InMemoryEventId.ChangesSaved })
                .UseInMemoryDatabase("UserContextWithNullCheckingDisabled")
                .EnableNullabilityCheck(false);
        }

Improved SQL Server translation for IsNullOrWhitespace

GitHub Issue: #22916. This feature was contributed by @Marusyk.

Consider the following query:

        var users = context.Users.Where(
            e => string.IsNullOrWhiteSpace(e.FirstName)
                 || string.IsNullOrWhiteSpace(e.LastName)).ToList();

Before EF Core 6.0, this was translated to the following on SQL Server:

SELECT [u].[Id], [u].[FirstName], [u].[LastName]
FROM [Users] AS [u]
WHERE ([u].[FirstName] IS NULL OR (LTRIM(RTRIM([u].[FirstName])) = N'')) OR ([u].[LastName] IS NULL OR (LTRIM(RTRIM([u].[LastName])) = N''))

This translation has been improved for EF Core 6.0 to:

SELECT [u].[Id], [u].[FirstName], [u].[LastName]
FROM [Users] AS [u]
WHERE ([u].[FirstName] IS NULL OR ([u].[FirstName] = N'')) OR ([u].[LastName] IS NULL OR ([u].[LastName] = N''))

Database comments are scaffolded to code comments

GitHub Issue: #19113. This feature was contributed by @ErikEJ.

Comments on SQL tables and columns are now scaffolded into the entity types created when reverse-engineering an EF Core model from an existing SQL Server database. For example:

/// <summary>
/// The Blog table.
/// </summary>
public partial class Blog
{
    /// <summary>
    /// The primary key.
    /// </summary>
    [Key]
    public int Id { get; set; }
}

Microsoft.Data.Sqlite 6.0 Preview 1

TIP You can run and debug into all the preview 1 samples shown below by downloading the sample code from GitHub.

Savepoints API

GitHub Issue: #20228.

We have been standardizing on a common API for savepoints in ADO.NET providers. Microsoft.Data.Sqlite now supports this API, including:

  • Save to create a savepoint in the transaction
  • Rollback to roll back to a previous savepoint
  • Release to release a savepoint

Using a savepoint allows part of a transaction to be rolled back without rolling back the entire transaction. For example, the code below:

  • Creates a transaction
  • Sends an update to the database
  • Creates a savepoint
  • Sends another update to the database
  • Rolls back to the savepoint previous created
  • Commits the transaction
        using var connection = new SqliteConnection("DataSource=test.db");
        connection.Open();

        using var transaction = connection.BeginTransaction();

        using (var command = connection.CreateCommand())
        {
            command.CommandText = @"UPDATE Users SET Username = 'ajcvickers' WHERE Id = 1";
            command.ExecuteNonQuery();
        }

        transaction.Save("MySavepoint");

        using (var command = connection.CreateCommand())
        {
            command.CommandText = @"UPDATE Users SET Username = 'wfvickers' WHERE Id = 2";
            command.ExecuteNonQuery();
        }

        transaction.Rollback("MySavepoint");

        transaction.Commit();

This will result in the first update being committed to the database, while the second update is not committed since the savepoint was rolled back before committing the transaction.

Command timeout in the connection string

GitHub Issue: #22505. This feature was contributed by @nmichels.

ADO.NET providers support two distinct timeouts:

  • The connection timeout, which determines the maximum time to wait when making a connection to the database.
  • The command timeout, which determines the maximum time to wait for a command to complete executing.

The command timeout can be set from code using <xref:System.Data.Common.DbCommand.CommandTimeout?displayProperty=nameWithType>. Many providers are now also exposing this command timeout in the connection string. Microsoft.Data.Sqlite is following this trend with the Command Timeout connection string keyword. For example, "Command Timeout=60;DataSource=test.db" will use 60 seconds as the default timeout for commands created by the connection.

TIP Sqlite treats Default Timeout as a synonym for Command Timeout and so can be used instead if preferred.

Daily builds

EF Core previews are aligned with .NET 6 previews. These previews tend to lag behind the latest work on EF Core. Consider using the daily builds instead to get the most up-to-date EF Core features and bug fixes.

As with the previews, the daily builds require .NET 5.


The EF Core Community Standup

The EF Core team is now live streaming every other Wednesday at 10am Pacific Time, 1pm Eastern Time, or 17:00 UTC. Join the stream to ask questions about the EF Core topic of your choice, including the latest preview release.

Documentation and Feedback

The starting point for all EF Core documentation is docs.microsoft.com/ef/.

Please file issues found and any other feedback on the dotnet/efcore GitHub repo.

The following short links are provided for easy reference and access.

EF Core Community Standup Playlist: https://aka.ms/efstandups

Main documentation: https://aka.ms/efdocs

Issues and feature requests for EF Core: https://aka.ms/efcorefeedback

Entity Framework Roadmap: https://aka.ms/efroadmap


Thank you from the team

A big thank you from the EF team to everyone who has used EF over the years!

ajcvickers Arthur Vickers AndriySvyryd Andriy Svyryd Brice Lambson JeremyLikness Jeremy Likness
maumar Maurycy Markowski roji Shay Rojansky smitpatel Smit Patel

Thank you to our contributors!

Ali-YousefiTelori AndrewKitu ardalis CaringDev
Ali-YousefiTelori AndrewKitu ardalis CaringDev
#1 #1 #1 #1
carlreinke cgrimes01 cincuranet dan-giddins
carlreinke cgrimes01 cincuranet dan-giddins
#1 #1 #1 #1
dennisseders DickBaker ErikEJ fagnercarvalho
dennisseders DickBaker ErikEJ fagnercarvalho
#1, #2, #3, #4, #5, #6 #1 #1, #2, #3, #4, #5 #1
filipnavara garyng Geoff1900 gfoidl
filipnavara garyng Geoff1900 gfoidl
#1 #1, #2, #3 #1 #1
gurustron HSchwichtenberg jantlee joaopgrassi
gurustron HSchwichtenberg jantlee joaopgrassi
#1 #1 #1 #1
josemiltonsampaio KaloyanIT khalidabuhakmeh khellang
josemiltonsampaio KaloyanIT khalidabuhakmeh khellang
#1 #1, #2 #1, #2 #1
koenbeuk kotpal leonardoporro Marusyk
koenbeuk kotpal leonardoporro Marusyk
#1 #1 #1 #1, #2
MaxG117 mefateah meggima msawczyn
MaxG117 mefateah meggima msawczyn
#1 #1 #1 #1
MSDN-WhiteKnight natashanikolic nmichels nschonni
MSDN-WhiteKnight natashanikolic nmichels nschonni
#1 #1 #1 #1, #2, #3, #4
pkellner ralmsdeveloper RaymondHuy Shirasho
pkellner ralmsdeveloper RaymondHuy Shirasho
#1 #1 #1, #2, #3, #4 #1
SimonCropp the-wazz tkp1n Tomkaa
SimonCropp the-wazz tkp1n Tomkaa
#1, #2 #1 #1 #1
umitkavala vincent1405 wmeints
umitkavala vincent1405 wmeints
#1, #2 #1 #1

Author

Jeremy Likness
Principal Program Manager - .NET Web Frameworks

Jeremy is a Principal Program Manager for .NET Web Frameworks at Microsoft. Jeremy wrote his first program in 1982, was recognized in the "who's who in Quake" list for programming the first implementation of "Midnight Capture the Flag" in Quake C and has been developing enterprise applications for 25 years with a primary focus on web-based delivery of line of business applications. Jeremy is the author of four technology books, a former 8-year Microsoft MVP for Developer Tools and Technologies, ...

More about author

10 comments

Discussion is closed. Login to edit/delete existing comments.

  • 杨 魏

    wo wo wo go go go study study study😍

    • Emma Rose

      As excited as you are with the jumble puzzle solver I also want to embed these codes on some of the custom project mine.

  • Ben Hayat

    Jeremy, any plans to cover MongoDB with EF6? As you guys already covering NoSQL with CosmoDB.

    • Jeremy LiknessMicrosoft employee Author

      Hi Ben! A MongoDB provider is not in scope for EF Core 6. We do plan to focus on improvements to the Azure Cosmos DB provider. What capabilities in EF Core are you looking to use that aren’t provided with the .NET MongoDB SDK?

      • Ben Hayat

        Hi Jeremy; Thanks for the reply and question;

        Back in 2007 I started with LINQtoSQL, and then EF Version 1 came out. What I loved about EF, vs. dealing directly with ADO.net for data access, was the fact, that as a consumer of data in my app, I was now under the protection and guidance of EF technology to perform data access. Being involved in DB app development since 1982, I've had my share of Wild...

        Read more
    • Ben Hayat

      I meant EF Core 6.

  • Theo Albers · Edited

    Hey Jeremy, I'm a little confused about the prerequisites.

    With EFCore 5.0 we run happily on .NET Core 3.1 due to the NS support:
    "...
    EF Core 5.0 requires a .NET Standard 2.1 platform. This means EF Core 5.0 will run on .NET Core 3.1 or .NET 5, as well as other platforms that support .NET Standard 2.1. EF Core 5.0 does not run on .NET Framework.
    ..."
    https://devblogs.microsoft.com/dotnet/announcing-the-release-of-ef-core-5-0/

    I guess this implies that running EFCore 6...

    Read more
    • Jeremy LiknessMicrosoft employee Author

      Hi, Theo. What are you confused about? Your statements are correct: EF Core 6.0 will run on .NET 5 or later and is aligned with .NET 6 in terms of LTS.

      Jeremy

  • kyle sheppard

    How about bulk updates in the database without loading to memory?

    • Tyler

      Deletes as well. Currently doing this using the .Remove(new Thing { Id = id }) trick, but some actual support would be great.