In our previous articles we looked at the new features of EF Core 2.0 and its criticisms. Today we’ll look at EF Core’s many breaking changes

EF Core 1.x Providers Not Supported

Database providers are how EF generates database-specific SQL for SQL Server, MySQL, etc. There is no generic OleDB or ODBC provider, so EF is limited by the providers created for it.

In an attempt to simplify provider development, EF Core has changed the provider APIs without offering a backwards compatibility option. This means that EF Core 1.0 and 1.1 providers are not supported by EF Core 2.0 and each will have to be rewritten using the EF Core 2.0 APIs.

According to Microsoft, “the open-source third party providers for SQL Compact, PostgreSQL, and MySQL are being updated for 2.0”. If you are using another database, Microsoft recommends that you contact the provider author.

IDbContextFactory Renamed to IDesignTimeDbContextFactory

Despite its name, the IDbContextFactory class was never meant to be used as a DbContext factory in applications. Rather, it was meant to only be used by design time tools that needed a DbContext for tasks such as generating database migration scripts.

In order to make this clear, IDbContextFactory has been marked as obsolete and tools will now call IDesignTimeDbContextFactory instead.

Along with this change, Microsoft is dropping support for DbContextFactoryOptions. It was decided that this wasn’t appropriate for design time context generation.

Logging and Diagnostics Events Changed

Changes to the logging and diagnostics for EF Core include:

The event IDs for messages sent to an ILogger have changed in 2.0. The event IDs are now unique across EF Core code. These messages now also follow the standard pattern for structured logging used by, for example, MVC.

Logger categories have also changed. There is now a well-known set of categories accessed through DbLoggerCategory.

DiagnosticSource events now use the same event ID names as the corresponding ILogger messages. The event payloads are all nominal types derived from EventData.

Though listed as a breaking change, Microsoft doesn’t expect this to have a significant impact on existing applications.

In-memory databases must be named

An important feature for test performance is the ability to create in-memory databases. While not a true representation of how the application will perform in production, it can nonetheless be useful when looking at problems in the business logic.

Previously EF Core supported a global, unnamed in-memory database. This is no longer an option and developers are now required to name each in-memory database. The same in-memory database can still be shared by multiple context instances.

Read-only API changes

EF Core is dropping support for IsReadOnlyBeforeSave, IsReadOnlyAferSave, and IsStoreGeneratedAlways. These were exposed by the IProperty interface. They have been replaced by the BeforeSaveBehavior and AfterSaveBehavior properties on IProperty. The documentation continues:

Properties marked as ValueGenerated.OnAddOrUpdate (e.g. for computed columns) will by default ignore any value currently set on the property. This means that a store-generated value will always be obtained regardless of whether any value has been set or modified on the tracked entity. This can be changed by setting a different Before\AfterSaveBehavior.

Since new fields are being added, this is also considered a breaking change for the IProperty interface itself.

Default Delete Behavior is now ClientSetNull

EF Core previously had three possibly behaviors for deletions involving optional relationships:

Cascade: Dependent entities are also deleted. This cascading behavior is only applied to entities that are being tracked by the context. A corresponding cascade behavior should be setup in the database to ensure data that is not being tracked by the context has the same action applied. If you use EF to create the database, this cascade behavior will be setup for you.

Restrict: The delete operation is not applied to dependent entities. The dependent entities remain unchanged.

SetNull: The foreign key properties in dependent entities are set to null. This cascading behavior is only applied to entities that are being tracked by the context. A corresponding cascade behavior should be setup in the database to ensure data that is not being tracked by the context has the same action applied. If you use EF to create the database, this cascade behavior will be setup for you.

A new option, which is now also the default, has been added called ClientSetNull.

In EF Core 2.0, a new ClientSetNull behavior has been introduced as the default for optional relationships. This behavior has SetNull semantics for tracked entities and Restrict behavior for databases created using EF Core. In our experience, these are the most expected/useful behaviors for tracked entities and the database. DeleteBehavior.Restrict is now honored for tracked entities when set for optional relationships.

Provider Design-time Packages Consolidated

In a minor bit of tidying-up, the Microsoft.EntityFrameworkCore.Relational.Design package has been dropped and its contents incorporated into the Microsoft.EntityFrameworkCore.Relational and Microsoft.EntityFrameworkCore.Design packages. The net effect is one less package that needs to be explicitly referenced.

In our next article we’ll be looking at the EF Core roadmap.