Entity Framework Core: High-Level Diagram

Entity Framework Core: High-Level Diagram

The below image illustrates the process of how a?LINQ?query is executed at a very high level:

  1. DbContext Instantiation
  2. DbContext Initilization
  3. Build Internal Service Provider
  4. Build Model
  5. Compile Query
  6. Execute Query


entity framework execution diagram

Let’s take the below code as an example:

example line 3

After the code at line number?3?is executed, only the step?DbContext Instantiation?is executed as?DbContext?is lazy, it will not do heavy stuff until you actually start using it.


Let’s continue our code execution, at line number?5, we start using the?DbContext?then a lot of things are going to happen.

Continue code execution, after?ToList()?is invoked,?Compile Query?and?Execute Query?take place too.

example line 5

Now that you see,?EF Core?does a lot of things in order to serve your query, and you might think that’s why it is slower than?Dapper?or?ADO, luckily isn’t that slow because?EF Core?is smart enough to leverage caching a lot, so for the subsequent queries it will not need to do all the heavy steps again and again.


DbContext Instantiation and Initialization

Now we will take a deeper look inside the?DbContext?class to find out how instantiation and initialization steps work.


DbContext Instantiation

Normally, when working with your DbContext, you often start your query with a query root, you can use the generic method?Set<TEntity>()?or you can also predefine some?DbSet?properties to name the Sets and don’t need to specify the generic type every time you want to work with.

For example:

DbSet

Now you can access a Set in 2 ways and both should work no differently to serve your query.

access DbSet

Hold a sec, you might be thinking when working with a class if you just define a property and never initialize it, oftentimes you will face the?NullReferenceException, so why does the code at line?10?never throw that exception.?

the answer is: DbSet?was initialized so we will never face the?NullReference Exception?here.


Now you might be wondering who did that? I know you already know the answer: EF Core, but how? Let’s dig deep into the EF Core source code next.

Let’s take a look at one of the DbContext constructors:

DbContext Constructor

focus on line?130?where EF Core tries to initialize all the DbSet properties you defined in your DbContext


DbContext Initialization

Because?DbContext?is lazy, it doesn’t do heavy stuff until you start using it, when you start working with the DbContext, it usually requires one of the properties of the?IDbContextServices ContextServices?property.

let’s see how?IDbContextServices ContextServices?is initialized the first time it is used.

IDbContextServices


It creates a?DbContextOptionsBuilder?instance using the?DbContextOptions _options (line 425)?(the one you pass into the constructor or default if you use the parameterless constructor) and then calls the?OnConfiguring?method (line 427).

In our?BloggingContext?example, the?OnConfiguring?method will be invoked and the?Sqlite Database Provider?is registered here.

BloggingContext


After the?Internal Service Provider?is created and cached, it creates a scope and resolves the?IDbContextServices, so basically each?DbContext?instance will have its own scope.


The internal service provider

EF will create a service provider (container) when an application using EF Core is started for the first time. EF Core is built in a service-oriented way, so this service provider is loaded with all the services that EF uses internally. EF uses the default implementation of?Microsoft.Extensions.DependencyInjection?for this service provider.

For most applications the internal service provider is an implementation detail of EF. Applications should not need to care about it at all.



Build a Model

EF Core uses a metadata model to describe how the application's entity types are mapped to the underlying database. This model is built using a set of conventions - heuristics that look for common patterns. The model can then be customized using mapping attributes (also known as data annotations) and/or calls to the ModelBuilder methods (also known as fluent API) in OnModelCreating, both of which will override the configuration performed by conventions.


Compile and Execute a Query

Entity Framework translates LINQ queries into SQL queries to retrieve data from the database. When you write a LINQ query in your code, Entity Framework parses the query and generates SQL statements to get the required data from the database.

Entity Framework uses an expression tree to represent the LINQ query, which is then converted into SQL by the provider (such as SQL Server provider). The provider then executes the SQL query against the database and retrieves the results.

The query execution process involves multiple steps including query parsing, query translation, query compilation, and query execution. Entity Framework handles all these steps behind the scenes to execute the LINQ query and retrieve the data from the database.


Compile and Execute a Query


要查看或添加评论,请登录

Vanasis Baboomi的更多文章

社区洞察

其他会员也浏览了