What is Entity Framework Core?

Entity Framework Core (EF Core) is an advanced, cross-platform, lightweight, and open-source version of the Entity Framework, evolving from Entity Framework 6.x. As of its latest release, EF Core 8, it has introduced significant updates since its 6.0 version in November 2021. EF Core serves as a powerful object-relational mapper (ORM) for software developers, facilitating database interactions using .NET objects and reducing the need for extensive database operation code. This iteration continues to enhance developer productivity and application performance across diverse database systems.

Entity Framework Core Architecture

To understand the EF Core hierarchy, we need to explore all its components, from the bottom up. So, have a look at the below table – it presents the Entity Framework architecture:

Component Role
Data source specific providers Abstracts the ADO.NET interfaces to connect to the database
Map provider Translates LINQ command tree into a database native SQL query. Includes Store-Specific bridge which translates the generic command tree into a store-specifica command tree.
EDM parser and view mapping Based on the SLD specification of the data model, maps the model onto a underlying relational database. It creates views of the data based on the conceptual model by aggregating data from multiple tables. It also splits entity update into multiple updates to the corresponding tables.
Query and update pipeline Processes queries, filters and update requests to convert them into canonical command trees which are then converted into store specific queries by the Map Provider.
Metadata services Handles all metadata related ot the entities, relationships and mappings.
Transactions Integrates into transactional capabilities of the underlying store if it is supported by the underlying store..
Conceptual layer API Exposes the programming model for coding against the conceptual schema. It follows the ADO.NET pattern of using Connection objects to refer to the map provider, using Command objects to send the query, and returning EntityResultSets or EntitySets containing the result.
Disconnected components Cache datasets and entity sets into the Embedded database.
Embedded database Stores the cached data.
Design tools Set of tools that simplifies mapping of the conceptual schema to the relational schema.
Programming layer Exposes Entity Data Model (EDM) to be consumed by the programming languages. It contains Object Services and Web Services components.
Object services Generates a code for CLR classes that has the same properties as the entity which enables instantiation of entities as .NET objects.
Web services Exposes entities as web services
High-level services Reporting and similar services that work on the entities and not on the relational data.
Complex Types support for Complex Types and JSON column mapping
Query translation Query translation for JSON and hierarchical data types, such as HierarchyId.
ORM improvements Improving the ORM's capability to handle complex data structures and utilize modern database functionalities

EF Core Version History

As we mentioned earlier, Entity Framework Core was born in 2016, but years have passed since then. By this time, we have witnessed several EF Core versions. For your convenience, we have compiled a table with brief information about them.

Version Release Date Description
EF Core 1.0 27 June 2016 First version after EF 6
EF Core 2.0 14 August 2017 Released with Visual Studio 2017 15.3 and ASP.NET Core 2.0
EF Core 3.0 23 September 2019 Released with Visual Studio 2019 16.3 and ASP.NET Core 3.0
EF Core 3.1 3 December 2019 Preferred long-term supported version until at least 3 December 2022.
EF Core 5 12 January 2021
EF Core 6 10 November 2021
EF Core 7 November 2022
EF Core 8 November 2023 Latest available version

At the point of writing this article, the latest available version is EF Core 8. Here is a short list of the changes in this version:

  • Support for Complex Types facilitates handling value objects without an identity key.
  • Enhanced mapping of primitive collections to JSON columns in databases improves data storage efficiency.
  • Support for HierarchyId improves management of hierarchical data structures.
  • Extensions to raw SQL queries allow for unmappable CLR types, increasing flexibility in data retrieval.

Example of Using Entity Framework Core ORM

Object-Relational Mapper (ORM) is a kind of bridge between strongly-typed objects and a relational data source. The purpose is to enable developers to work with the data stored in databases in an object-oriented way. To achieve that, EF Core ORM provides a map between the objects defined in the application domain and the data stored in the database.

A typical way to work with relational databases is through some kind of recordset-like data structure. Assume we need to retrieve a list of students from the database. We can do it through ADO.NET:

using (var conn = new SqlConnection(connString))
{
	using (var da = new SqlDataAdapter("SELECT * FROM 
[dbo].[Students]", conn))
	{
		var dt = new DataTable();
		da.Fill(dt);
		foreach (DataRow dr in dt.Rows)
		{
			Console.WriteLine("\t{0} - {1} {2} - {3}",
				dr["BirthYear"],
				dr["FirstName"],
				dr["LastName"],
				(int)dr["Gender"] == 1 ? "Male" : "Female");
		}
	}
}
public class Student
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int BirthYear { get; set; }
   public GenderType Gender { get; set; }
   public GenderType Gender { get; set; }
   public string Interests { get; set; }
}
public enum GenderType { Female, Male }

The problem is, this approach to data access is prone to errors. The code may compile in without any issues but problems can show up in runtime. Common errors happen because the code might not reflect the state of the data source. Or, we might address columns that are removed or changed, or with incorrect column names.

The strongly-typed approach to the data suggests using definite classes in an object-oriented way.

We still need to retrieve the data from the database and map it to our data model. That is where Entity Framework Core ORM enters.

ORMs are pre-written libraries that ensure the following tasks:
  • map the domain model to database objects
  • create databases and maintain schema in line with changes to the model generate SQL scripts and execute them against the database
  • manage transactions
  • keep track of already retrieved object
var ctx = new MyDbContext();
var query = ctx.Students.ToList();

foreach (Student student in query)
{     
	Console.WriteLine("\t\{0} - {1} {2} - {3}",
		student.BirthYear,
		student.FirstName,
		student.LastName,
		student.Gender);
}

EF Core vs Entity Framework 6

Entity Framework Core 8, released in November 2023, now aligns with .NET 8, ensuring compatibility with current applications on .NET 6 and 7, while older applications should upgrade for full functionality. This version focuses on performance enhancements and introduces features like Complex Types, improved JSON column mapping, HierarchyId support, and advanced raw SQL query capabilities for unmappable CLR types. Security enhancements include enabling encryption by default and requiring valid server certificates and client trust to avoid SqlExceptions, primarily affecting Microsoft SQL Server users. Additionally, EF Core 8 optimizes change tracking and saving efficiency, albeit with considerations for SQL Server's database triggers and computed columns.

Creating a Model

Feature EF 6.4 EF Core
Basic class mapping Yes 1
Constructors with parameters 2.1
Property value conversions 2.1
Mapped types with no keys 2.1
Conventions Yes 1
Custom conventions Yes 1.0
Data annotations Yes 1
Fluent API Yes 1
Inheritance: Table per hierarchy (TPH) Yes 1
Inheritance: Table per type (TPT) Yes 5
Inheritance: Table per concrete class (TPC) Yes 7
Shadow state properties 1
Alternate keys 1
Many-to-many navigations Yes 5
Many-to-many without join entity Yes 5
Key generation: Database Yes 1
Key generation: Client 1
Complex/owned types Yes 2
Spatial data Yes 2.2
Model format: Code Yes 1
Create model from database: Command line Yes 1
Global query filters 2
Table splitting Yes 2
Database scalar function mapping Poor 2
Database table valued function mapping Poor 5
Field mapping 1.1
Nullable reference types (C# 8.0) 3
Update model from database* Partial Yes*
Graphical visualization of model* Yes Yes*
Graphical model editor* Yes Yes*
Create model from database: VS wizard* Yes Yes*

* Available in Entity Developer.

Pay attention to these differences if you think to migrate Entity Framework 6 to Core. It can be more reasonable to keep both the systems until Core gets everything it lacks now.

Querying Data

Feature EF 6.4 EF Core
LINQ queries Yes 1
Readable generated SQL Poor 1
GroupBy translation Yes 2.1
Loading related data: Eager Yes 1
Loading related data: Eager loading for derived types 2.1
Loading related data: Lazy Yes 2.1
Loading related data: Explicit Yes 1.1
Raw SQL queries: Entity types Yes 1
Raw SQL queries: Keyless entity types Yes 2.1
Raw SQL queries: Composing with LINQ 1
Explicitly compiled queries Poor 2
await foreach (C# 8.0) 3
Text-based query language (Entity SQL) Yes

Pay attention to these differences if you think to migrate Entity Framework 6 to Core. It can be more reasonable to keep both the systems until Core gets everything it lacks now.

Saving Data

Feature EF 6.4 EF Core
Change tracking: Snapshot Yes 1
Change tracking: Notification Yes 1
Change tracking: Proxies Yes 5
Accessing tracked state Yes 1
Optimistic concurrency Yes 1
Transactions Yes 1
Stored procedure mapping Yes
Disconnected graph low-level APIs Poor 1
Disconnected graph End-to-end Poor 1.0

Pay attention to these differences if you think to migrate Entity Framework 6 to Core. It can be more reasonable to keep both the systems until Core gets everything it lacks now.

Other features

Feature EF 6.4 EF Core
Migrations Yes 1
Database creation/deletion APIs Yes 1
Seed data Yes 2.1
Connection resiliency Yes 1.1
Interceptors Yes 3
Events Yes 3.0
Simple Logging (Database.Log) Yes 5
DbContext pooling 2

Pay attention to these differences if you think to migrate Entity Framework 6 to Core. It can be more reasonable to keep both the systems until Core gets everything it lacks now.

Entity Framework Core 8

Entity Framework Core 8, released in November 2023, now aligns with .NET 7, ensuring compatibility with current applications on .NET 6 and 7, while older applications should upgrade for full functionality. This version focuses on performance enhancements and introduces features like Complex Types, improved JSON column mapping, HierarchyId support, and advanced raw SQL query capabilities for unmappable CLR types. Security enhancements include making encryption enabled by default, requiring valid server certificates and client trust to avoid SqlExceptions, primarily affecting Microsoft SQL Server users.

Additionally, EF Core 8 optimizes change tracking and saving efficiency, albeit with considerations for SQL Server's database triggers and computed columns.

ADO.NET Data Providers with EF Core Support

Entity Framework Approaches

Entity Framework Core supports two development approaches: Database First and Code First. Besides, there is the Model First approach — it is supported in EF 6.4 but is not in EF Core now.

With Entity Developer, you can seamlessly switch between Database First, Code First, and Model First workflows and choose the most suitable approach for your projects.

Entity Framework Approaches

Database First Approach

Database First suggests creating the data model from the existing database and tables.

Database First in Entity Framework Core creates DbContext and Domain classes based on the existing database schema. Additionally, GUI tools like Entity Developer can be used to streamline this process.

For example, we have an existing database with the following structure:

For example, we have an existing database with the following structure

We run the following command to build our application data model:

PM> Scaffold-DbContext "Data Source=SQLEXPRESS;Initial 
Catalog=FacultyDatabase;Integrated Security=True" 
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

The result are these data model classes:

For example, we have an existing database with the following structure

This is an illustration of the EF Core db first approach, so you can see how it works.

Code First Approach

Code First suggests the creation of the application domain classes first. That includes a special class that derives from the EF DbContext class. As for the Code First in Entity Framework Core, it is based on the domain entity classes and DBContect class. This way, EF Core creates databases and corresponding tables.

By default, EF Core API creates the database and tables using migration classes based on the default conventions and configuration. It is possible to customize these settings to adjust the model to the business requirements. This is common in Domain-Driven Design (DDD).

Once we have the data model classes and DbContext class created, we can use the Code First to generate the database.

Let us have a look at the example of the Entity Framework Core Code First. We will use classes generated in the Database First example and generate a new database FacultyDatabase2 and the corresponding tables.

Run the following command to generate the initial migration class:

PM> Add-Migration FirstMigration

This will result with the FirstMiration class.

Now we can use update-database command to generate the database.

If the command ends successfully, we will get the database with the identical structure as the initial database. This is how the Code First in .NET Core works.

There is one more approach we should review, so let us proceed.

Model First Approach

Model First requires that we use the EDMX editor to create the data model. This editor creates entities, relationships, and inheritance hierarchies in the design surface. The database is created based on that model.

However, as we already mentioned, Model First is not available in Entity Framework Core at the moment. It does not mean it will not be added in the further versions, but if you need the Entity Framework Core model first now, it won't work, unfortunately. In the meantime, Entity Developer addresses this temporary inconvenience by introducing new approaches for designing ORM models, enhancing productivity, and facilitating the development of database applications.

Model First Approach

EF Core Tips and Best Practices

Entity Framework Core is good at abstracting details. And it offers great prospects to specialists. Here we offer you some Entity Framework performance tips that will help you achieve the best results.

Database

You need to understand the underlying database to design, debug and maintain production app performance at the highest possible level.

Functional

Try to replicate the production environment in functional and integration testing as close as possible. It allows you to catch errors that can be caused by the server version's compatibility.

Test your application

Stress test your application with the representative loads.

Security guidelines

Always follow the security guidelines.

Optimize

Optimize logging configuration.

Plan for possible failures

Prepare a plan for possible failures such as version rollback, server fallback, etc.

Migration

Prepare a plan for application deployment and migration during the deployment. Doing migrations at the application start can cause concurrency issues.

Examination

Do the detailed examination and testing of the generated migrations. Database schema and column types cannot be easily changed if the database already contains data.

These Entity Framework Core best practices when applied regularly bring excellent results, so we do recommend making a good habit of using them.

Connect to Data Effortlessly in .NET

Streamline Your .NET Projects with feature-rich ADO.NET providers with ORM support