Creating an Application from Scratch using .NET Core and Angular — Part 2
In this article we are going to see how to create the Models (our entities) in the domain layer, create the migrations and the database using Entity Framework Core, and we are also going to use the Fluent API for mapping our entities to the database.
In the Domain project, let’s create the ‘Models’ folder, and also create our entities: Book, Category and Entity classes:
Those entities that we are going to create, will become the tables in the database. So let’s start implementing an abstract class for ‘Entity’, which will contain an Id of type ‘int’:
This is an abstract class because this class cannot be instantiated, it only can bee inherited. All other entities will inherit from this class. The difference between an abstract class and an interface, is that an abstract class can have logic, and the interface it’s just a contract which specifies what are the methods or properties.
We are going to have two entities, that will be two tables in the database, the Book and the Category. Let’s keep in mind that one book must have one category, and a category can belong to many books.
Now we are going to create the Category and the Book classes, and both are going to inherit from the Entity class:
To create a relationship between classes we can use Inheritance and Composition. I’m not going to explain the difference between them in this article, but if you want to know more about it you read my other article ‘Inheritance and Composition’ where I explain the difference between then and when you should use each one.
We need the CategoryId property in the Book class, because then the Entity Framework understand that this is the foreign key. The Category property in line 15 it’s for the EF recognizes that there is a relationship.
Let’s also implement the Category class:
In this project, we need to add a reference to the Domain project. Right click in ‘Dependencies’ and click on the option ‘Add Reference…’:
Then you should select the BookStore.Domain project and click in ‘Ok’:
We also need to add the Entity Framework Core in our project.
Open the Package Manager Console:
Select the Infrastructure project and let’s install the necessary tools to work with EF Core and migrations:
Execute all those commands:
Install-Package Microsoft.EntityFrameworkCore -Version 3.1.5
Install-Package Microsoft.EntityFrameworkCore.Tools -Version 3.1.5
Install-Package Microsoft.EntityFrameworkCore.Design -Version 3.1.5
Now let’s create a folder for our Entity Framework Context, and also create the class BookStoreDbContext:
This is the BookStoreDbContext class:
In this class, we are defining our DbSets in the lines 11 and 12. This is a definition from the Microsoft documentation about what is a DbSet:
A DbSet represents the collection of all entities in the context, or that can be queried from the database, of a given type. DbSet objects are created from a DbContext using the DbContext.Set method.
The DbSets represents a collection of an entity. It’s a good practice that you use the name of your DbSets in the plural.
Mapping the Entities with Fluent API
We are going to use the Fluent API to configure and mapping the properties and the types of our entities to the database.
For that let’s create a folder with the name ‘Mappings’, and create the classes BookMapping and CategoryMapping. Those classes must inherit from ‘IEntityTypeConfiguration<T>’:
We also need to instal this package in the Infrastructure project to do the mapping:
Install-Package Microsoft.EntityFrameworkCore.Relational -Version 3.1.5
This is the CategoryMapping class:
The ‘HasKey’ it’s to set the Id property as the Primary Key. If we do not define that, EF would also use the Id as the Primary Key, but with this configuration, we can be sure that it will use exactly how we configured.
For the Name property, we defined that it is required and that the column can have up to 150 characters.
We also defined the 1 : N relationship. A category can have many books, and the Book needs to have one category, and we set the CategoryId property (that is inside the Book class) as the Foreign Key of this relationship.
And with the ‘ToTable’ we define the name of the table in the database.
This is the BookMapping class:
We defined on this mapping the size of the string properties, and also defined that all properties are required, except the Description property.
Configuring the DbContext
Now we need to add some code in the class BookStoreDbContext, I will show how it is now and will explain what was added:
We overrode the method OnModelCreating (that is the method that will be called during the creation of the model in the database) and added some configurations.
By default, if we forgot to define the size of any property of type string, it will be created as nvarchar(max), to avoid that, we added a configuration (in line 16) that will create the size of the column in the database as varchar(150) for the columns of type string that were not mapped. This is good to use in projects which you will have more classes.
The code in line 21, will access the BookStoreDbContext, and it will see all the entities that are mapping inside of the BookStoreDbContext and search the classes that inherit from the IEntityTypeConfiguration, and then it will register all of them. So for each mapping class that we had configured, it will be registered through this command.
In line 23 we added the code to disable the cascade deletion. And that is because we do not want that when we delete one record from one table, the relational data in the other table be removed too. We will have validation for that in our code later.
In this layer we need to add now the reference for the Infrastructure project:
Select the project and click in ‘Ok’:
We also need to install in our project:
Install-Package Microsoft.EntityFrameworkCore.Design -Version 3.1.5
We need to configure the connection string to access the database. To do that, open the appsettings.json file:
Let’s add our connection string below the ‘AllowHosts’. We are going to use a local database, so the server will be our localdb. The class should be now like this:
In the Startup class, we are going to add the configuration to access the database. Open the Startup.cs:
Add the configuration to access the database in the method ConfigureServices. Should now be like this:
We also need to add the using in the top of the class:
The ‘DefaultConnection’, must be the name that we defined in the file appsettings.json.
This is a definition of Migrations from the Microsoft documentation:
The migrations feature in EF Core provides a way to incrementally update the database schema to keep it in sync with the application’s data model while preserving existing data in the database.
When you create a Migration, it will generate a script to update or downgrade the database.
You can create the migrations using the Package Manager Console in Visual Studio or using command line. The command to create in Visual studio is:
Now you should see these two files in your project:
To apply the migration in the database, we need to execute this command:
Command in the Package Manager Console in Visual Studio:
In Visual Studio, you can go to View option and open the SQL Server Object Explorer, and you will see the database with the tables that were create through the migrations:
Generate Script Migration
If you want to see the SQL script that is generated from the migrations, you need to install this package:
Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 3.1.5
And then you can execute this command:
Commit the code to GitHub
Now let’s commit the code in GitHub as we did in the previous article. To see the files that were changed or added, you need to open the command line and go to the folder of your project and execute this command:
To commit the code, use those commands (run each one separately):
git add .git commit -m "Created entities and BookStoreDbContext"git push origin master
In the next part, we are going to create the Interfaces, the Repositories, and the Services. You can access the part 3 clicking here.
This is the link for the project in GitHub:
Thanks for reading!