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.
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.
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.
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.
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.
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.