In previous post, we have discussed what is migration and what are some basic dotnet CLI commands which can be used for adding / removing migrations.
Practically, those commands cannot be executed if you do not have EF Core models. So, in this article, let’s try to create a class library to setup a simple database – “MyUniversity“, which would contain a very simple and single table “Students” which will hold some basic information about users.
Note that we are not going to write data layer code to access data from database. Focus of this article is to explain the steps required to setup a new EF Core model using Code First approach and EF Core migrations. At the end of article, we will run migrations and check that database is created.
Prerequisite
You should have .NET SDK installed on your machine. You should also have a SQL Server (Express version) installed. You can either use Visual Studio or Visual Studio Code using dotnet CLI for creating project. For running migration commands, we are going to use DOTNET CLI tools mentioned in previous article.
Create Class Library Project
Let’s create a .NET Core class library project using Visual Studio. Let’s name it “University.Data.EF.Models“. This is the library that we will use to define EF core models. In upcoming articles, we will use this library as reference to demonstrate data access code and some other concepts.
As we are going to use SQL Server Express as the data store, let’s add the NuGet packages mentioned below. Below command can be run in package manager console. Alternatively, you can use Manage Nuget Packages option from Visual Studio.
First and second command install Entity Framework Core basic implementations and SQL Server specific components respectively. Third command is to install design time components for Entity Framework Core tools.
Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Design
Create EF Core Model
Now, let’s create a simple POCO class , Student as shown in below code snippet. This class would serve as EF Core model. Note that currently this class only specifies properties and their data types. But in real world, database table schema might need more details. For example, specifying primary / foreign keys, autogenerated keys, cascade delete in case related entity is deleted, etc.
Entity Framework Core also provides many constructs to enable adding such features via EF Core models. But we will ignore them purposefully for limiting the scope of this article.
Create UniversityContext
Now, let’s add a new class – UniversityContext – which extends DbContext. Also add a constructor of this class to accept DbContextOptions<UniversityContext> parameter. This parameter should also be passed to the constructor of base class. This parameter encapsulates some important inputs (e.g. connection strings).
Note that DbContext can also have public constructors which do not need any inputs. In that case, DbContext class needs to implement DbContext.OnConfiguring method to populate the DbContextOptions. Let’s not use parameter-less default constructor for this demo.
This context should also define DbSet<Entity> property. This DbSet property corresponds to a database table. The entity (in our case Student class) corresponds to a row in that table.
Implement IDesignTimeDbContextFactory
When a DbContext implementation does not have a default public interface, generating migration is not easy. The EF Core tools would not be able to create instance of concrete DbContext (i.e. UniversityContext) and hence they cannot generate migrations. So, to facilitate creation of such DbContext, it is important to implement IDesignTimeDbContextFactory.
Design tools can automatically detect this implementation if it is in the same class library.
Below code shows the implementation that we should add in the class library.
Migrations
So, we have the EF Core model ready now. I assume that you have installed the dotnet-ef tool already. If not, please refer this blogpost.
Now, run below commands. First command is to generate migration file. Second command is to apply migrations to the SQL database.
Run and Verify
Once, above two commands are executed, you should be able to Migrations directory added to the class library project. Also, if you open SSMS and connect to the appropriate database instance, you should be able to see the database University created. It should have Students table. It has one more additional table, which is used to track migrations. We will talk about tracking migrations later sometime.
I think you should have fair idea about what you need to add additional tables to this database. In coming articles, we will see how database constraints can be enforced via EF Core code first approach.
I hope you find this information useful. Let me know your thoughts.
Pingback: The Code Blogger - Common Data Annotations to Configure EF Core Model
Pingback: The Code Blogger - Database schema for blog management using .NET EF Core
Pingback: The Code Blogger - EF Core Repository with Specification Pattern in .NET
Pingback: The Code Blogger - Map CLR Method to a SQL Function using .NET EF Core
Simple and to the point. Thank you…
There is an error with the IDesignTimeDbContextFactory implementation.
CS0050 Inconsistent accessibility: return type ‘UniversityContext’ is less accessible than method ‘DesignTimeUniversityContextFactory.CreateDbContext(string[])’
I believe this is simple C# access modifiers issue. If you correct the access modifiers for UniversityContext, then it should work as expected.