Accessing Data
Now that we have connected our C# application to a MySQL database, we need to set up our C# code to interact with the new schema. In the previous chapters, we learned about performing basic operations on a database and its tables, such as creating, reading, updating, and deleting rows. One of the reasons we use ORM is so that now we can write C# code in our application to manage our relational database.
While classes determine the structure of a table in our relational database, a data store does the work of inserting, updating, and retrieving data from the database.
In our work so far, we have been using an in-application data store. This is the class EventData
. The EventData
class is an in-memory data store. It keeps track of new events using a C# data structure, which gets deleted from memory every time the app shuts down. With EF, we can create a persistent data store. A persistent data store retains data even when an app shuts down.
Creating a DbContext
We are going to use the DbContext
class. This class
works with databases to track and manage changes in our stored data.
Create EventDbContext
Class
In the
Data
directory, create a new class calledEventDbContext
.By convention, we name it
EventDbContext
since it is going to be used to work with Event objects and data.To create a persistent data store for our
Event
class, we can extend the classDbContext
, which is provided by EF. This will provide the base functionality we need.Check Your Codepublic class EventDbContext : DbContext
This class needs a
using Microsoft.EntityFrameworkCore;
statement. Visual Studio’s Intellisense should automatically add it for you.DbContext
is often paired withDbSet<Entity>
which represents the collection of all entities of a given type that can be queried from the database.We are going to create a
DbSet<Entity>
ofEvent
types and name itEvents
. This will allow us to queryEvent
objects once our database is created.DbSet<Events>
will need access to theEvent
Model class. Make sure you provide the appropriate using statement.Check Your Code9 10 11 12 13
public DbSet<Event> Events { get; set; } public EventDbContext() { }
We want to the
EventDbContext
constructor to extendDbContextOptions
. This will configure the data store.Check Your Code1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
using CodingEvents.Models; using Microsoft.EntityFrameworkCore; namespace CodingEvents.Data { public class EventDbContext : DbContext { public DbSet<Event> Events { get; set; } public EventDbContext(DbContextOptions<EventDbContext> options) : base(options) { } } }
This basic data store template can be used for any class that you want to persist in a database. Each such class will need its own data store.
Registering a Data Store
To make ASP.NET aware of this data store, we need to register EventDbContext
in the Program class
. Program
is automatically executed every time our app starts up, and is a place where application configuration can be customized.
A persistent data store is considered a service in ASP.NET. We need register this service by applying the following code to Program.cs
:
|
|
This code adds EF Core as a service to our CodingEvents
application. Using the AddDbContext<EventDbContext>(...)
to configure the CodingEvents
database context options.
The MySql()
method is passed the connectionString
and serverVersion
variables which provide us access to the correct database. A single application may have multiple database connections.
When WebApplication.CreateBuilder(args);
runs in line 5 of Program.cs
, the connection to the database begins.
Configuring a Primary Key
As you learned previously , every relational table should have a primary key. When working with ORM, this means that every persistent class needs a primary key property. A persistent class is a class that we want to store (or persist) in a database.
Our Event
class currently has an ID field.
|
|
When introducing this property previously, we intentionally named it Id
in anticipation of using EF and a data store to persist Event
objects. EF will automatically configure any property named Id
to be the primary key for that class. Therefore, we already have the necessary property!
So the code sample above can be simplified to the following.
|
|
Be sure to update your Event
class to match the simplified codeblock above before you move on to the next section.
Migrations
Our application is now completely configured to store Event
objects in our MySQL database. However, if you look at the coding-events
database, youāll notice that it has no table in which to store such data. To create such a table, we need to create and run a database migration. A database migration (or migration, for short) is an update to a database made in order to reflect changes in an applicationās model. Every time we change our applicationās model by adding or removing a new persistent class, or by modifying a persistent class, we will need to create and run a migration.
The EntityFrameworkCore Tools package we installed in the last section provides tools for working with migrations. To get started, open a terminal (the Terminal app on MacOS or Powershell on Windows). Navigate to the CodingEvents
project folder
within your CodingEvents
solution.
Then run the following command to create a migration:
$ dotnet ef migrations add InitialMigration
This instructs the EF tools to create a migration named InitialMigration
. In doing so, EF scans our project looking for persistent classes (i.e. classes with data stores that have been registered in Startup) and compares them to the current state of the MySQL database. If any classes have been added, removed, or changed, it will generate code to update the database to be in sync with the applicationās model. This code is stored in the Migrations/
folder of your project.
In order to run a migration, we issue the command:
$ dotnet ef database update
This command will apply the changes to the database. To verify the changes, open MySQL Workbench and notice that there is now an Events
table with columns corresponding to the properties of our class.
EntityFrameworkCore uses the _EFMigrationsHistory
table in the database to keep track of which migrations have already been run. When we run dotnet ef migrations update
, EF will reference this table and run all migrations that have not yet been applied, in the correct order.
The next section will look at how we can store and retrieve Event
objects from within our controller.
Check Your Understanding
True/False: Every persistent class will automatically have a MySQL table created to use to store its data.
A data store should extend which of the following classes in the Microsoft.EntityFrameworkCore
package?
DataStore
DbContext
MySqlStore
- None of the above