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
Datadirectory, create a new class calledEventDbContext.By convention, we name it
EventDbContextsince it is going to be used to work with Event objects and data.To create a persistent data store for our
Eventclass, we can extend the classDbContext, which is provided by EF. This will provide the base functionality we need.Check Your Codepublic class EventDbContext : DbContextThis class needs a
using Microsoft.EntityFrameworkCore;statement. Visual Studio’s Intellisense should automatically add it for you.DbContextis 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>ofEventtypes and name itEvents. This will allow us to queryEventobjects once our database is created.DbSet<Events>will need access to theEventModel class. Make sure you provide the appropriate using statement.Check Your Code9 10 11 12 13public DbSet<Event> Events { get; set; } public EventDbContext() { }We want to the
EventDbContextconstructor to extendDbContextOptions. This will configure the data store.Check Your Code1 2 3 4 5 6 7 8 9 10 11 12 13 14 15using 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 InitialMigrationThis 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 updateThis 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?
DataStoreDbContextMySqlStore- None of the above