Notes from Razor Pages with Entity Framework Core in ASP.NET Core - Tutorial 1 of 8 | Microsoft Learn
creating a database
Program.cs
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
// DbInitializer.Initialize(context);
}
The EnsureCreated
method checks if the database exists. If not, it creates the database and schema.
This allows for the following workflow for data model changes:
- Delete the database
- Change the data model (ie: add an EmailAddress field)
- Run the app
EnsureCreated
will create a database with the new schema
When data exists that cannot be lost, use migrations instead of EnsureCreated
.
connection strings
Connection strings are passed to DbContexts
by calling a method on a DbContextOptions
object.
In local development, ASP.NET Core reads the string from appsettings.json
or appsettings.Development.json
.
primary keys
By default, EF Core interprets a property that’s named ID
or *classname*ID
as the primary key.
navigation properties
Navigation properties are properties in a model that hold other entities related to this entity. For example, a Student
may have a navigation property of Enrollments
to hold all the Enrollment
entities for that Student
.
EF Core interprets a property as a foreign key if it’s named <navigation property name><primary key property name>
. For example, StudentID
is the foreign key for the Student
navigation property, since the Student
entity’s primary key is ID.
- Foreign key properties can also be named
<primary-key-property-name>
such asCourseID
since theCourse
entity’s primary key isCourseID
.
seeding a database
Convention: create Data/DbInitializer.cs
with code to
seed a database with test data.
scaffolding
EF Core’s scaffolding engine does not support nullable reference types—the models used in scaffolding cannot use them either.
Scaffolding will automatically register the Context class it creates with DI.
Database Context (DbContext)
The database context class derives from Microsoft.EntityFrameworkCore.DbContext
and specifies which entities are included in the data model. It is the main class that coordinates EF Core functionality for a given data model.
This class lives in Data/*Some*Context.cs
. This service is registered with DI.
Entity Set (DbSet)
An entity set typically corresponds to a database table.
An entity corresponds to a row in the table.
entity states
The DbContext
keeps track of the sync state between entities in memory and their corresponding rows in the database.
An entity has these states:
Added
—entity does not yet exist in database;SaveChanges
will issue anINSERT
statementUnchanged
—no changes to this entityModified
—some or all of the entity’s properties have been modified;SaveChanges
issues anUPDATE
statementDeleted
—entity marked for deletion;SaveChanges
issues aDELETE
statementDetached
—entity is not being tracked by database context
visual studio
Visual Studio can view databases: View > SQL Server Object Explorer (SSOX)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
This package provides ASP.NET Core middleware for EF Core error pages.
asynchronous programming in ef core
EF Core uses async operations by default. However:
- Only statements that cause queries or commands to be sent to the database are executed asynchronously.
- An EF Core context is not thread safe — do not execute parallel operations.
reading entities
To read a single entity, prefer FirstOrDefaultAsync
(which returns null if nothing is found) over:
SingleOrDefaultAsync
which throws an exception if there’s more than one entity that satisfies the query filterFindAsync
because you cannot useInclude
with this method.
However, when you do not have to use Include
for related data, prefer FindAsync
as it is more efficient.