Create Database From Model Using EFCore

Visual Studio Entity Framework Core

In this post, I explain how to create a database from model using Entity Framework Core (EFCore) and create the database when the application is starting.

I have talked about Entity Framework in my previous posts:

While working with Entity Framework Core and ASP.NET Core you typically create EF Core model consisting of a custom DbContext and entity classes. If your database already exists, it can be mapped with the EF Core model. However, if the database doesn’t exist already, you would want it to be created. Of course, you can create the database manually by looking at the EF Core model and creating tables accordingly. Wouldn’t it be nice if the database gets created automatically for you based on the EF Core model your created? To that end this article discusses just that.

To begin with, create a new ASP.NET Core MVC application (you can create Razor Pages app if you want).

Now add these two NuGet packages to the project:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Design

The first NuGet package is the EF Core provider for SQL Server whereas the second NuGet package is needed when you use EF Core migrations (discussed later). 

NuGet Package Manager - Create Database From Model Using EFCore
NuGet Package Manager

Create classes for data

So, to create Database From Model Using Entity Framework Core (EFCore), we have to create first a database structure. Then, add a new folder to the project called DataAccess. The DataAccess folder stores the DbContext and entity classes required for the example discussed in this article.

Then add two classes – Customer and Order – in the DataAccess folder. The following code shows Customer class.

[Table("Customers")]
public class Customer
{
    [Column("CustomerID")]
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    public int CustomerID { get; set; }

    [Column("CustomerName")]
    [Required]
    [StringLength(100)]
    public string FirstName { get; set; }

    [ForeignKey("CustomerID")]
    public virtual List<Order> Orders { get; set; }
}

As you can see the Customer class is a POCO that uses data annotations to indicate the primary key, identity, and foreign key. Especially notice the Orders property that is intended to store all the orders belonging to a customer. Although we won’t use this class to perform CRUD operations in this example, we still added Orders property to illustrate how the database schema is created for us.

On the same lines add Order class as shown below:

public class Order
{
    [Column("OrderID")]
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    public int OrderID { get; set; }

    [Column("OrderDate")]
    [Required]
    public DateTime OrderDate { get; set; }

    [Required]
    public int CustomerID { get; set; }
}

The CustomerID in the Order class indicates a CustomerID this order belongs to.

Add the DbContext

Next, add a custom DbContext class named AppDbContext and write the following code in it:

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }
    public DbSet<Customer> Customers { get; set; }
    public DbSet<Order> Orders { get; set; }
}

As you can see, AppDbContext contains two DbSet properties – Customers and Orders. This completes a sample EF Core model required for our examples.

Build the project just to ensure that compiler is happy with our code.

Now open the appsetttings.json file and store a database connection string as shown below:

"ConnectionStrings": {
  "MyNewDatabase": "data source=.; initial catalog=MyNewDb; integrated security=true"
}

Note that the database specified in the connection string (MyNewDatabase) doesn’t exists at this point. It will be created for you in the following sections.

At this point, our EF Core model is ready and you can register the DbContext with the DI framework. To do that open the Startup class and add this code to the ConfigureServices() method.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddDbContext<AppDbContext>
      (o=>o.UseSqlServer(Configuration.
      GetConnectionString("MyNewDatabase")));
}

The above code uses AddDbContext() method to register AppDbContext with the DI system of ASP.NET Core. Notice that the database connection string stored in the appsettings.json file is supplied to the UseSqlServer() method.

Creating database using EnsureCreated() method

Now that the EF Core model is ready, let’s try to create the required database using EnsureCreated() method. This technique is a code based technique and works great for quick and simple database creation scenarios. This approach doesn’t use EF Core Migrations. All it does is to create a database schema based on your EF Core model. If a database already exists then no action is taken, otherwise the database is created for you.

To use the EnsureCreated() method go to the Configure() method and add the following code:

public void Configure(IApplicationBuilder app, 
IWebHostEnvironment env, AppDbContext db)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    db.Database.EnsureCreated();

    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/
{action=Index}/{id?}");
    });
}

Notice the code marked in bold letters. It injects AppDbContext instance to the Configure() method so that the instance can be used inside the method. Inside, the code calls the EnsureCreated() method to ensure that the database for the DbContext is created if it doesn’t exist already.

Now run the application and check whether the MyNewDb database gets created for you. The following figure shows this newly created database in SQL Server Object Explorer.

My new database on SQL Server Object Explorer - Create Database From Model Using EFCore
My new database on SQL Server Object Explorer

Notice how various tables, columns, column data types, primary keys, foreign keys are picked based on the EF Core model.

Creating database using EF Core Migrations and .NET Core CLI

The database creation approach discussed in the previous section is suitable for quick testing. A more realistic and recommended approach is to use EF Core Migrations to create and update database. This approach can not only create a database from ground-up, it can also update an existing database with changes (existing data is also preserved). Using EF Core migrations is a two step process – firstly you create a migration and secondly you apply that migration to a database.

Let’s see how these steps can be performed in our example.

Commands

Open Visual Studio command prompt and navigate to the ASP.NET Core project’s root folder.

Then install a .NET Core CLI tool called dotnet-ef. This is typically a one time operation. If you have already installed dotnet-ef tool then you don’t need to install it again.

Issue the following command to install dotnet-ef tool on your machine.

dotnet tool install dotnet-ef --global

The above command installs the latest stable version of dotnet-ef tool globally on your machine. You can also use –version option to specify a particular version of the tool.

You can check if the tool is installed or not by issuing the following command:

dotnet tool list --global

Next, you need to create a migration issuing the following command:

dotnet ef migrations add MyBaseMigration 
  --context AppDbContext

The above command creates a new migration named MyBaseMigration and uses a DbContext as specified by the –context option.

If all goes well, you will find Migrations folder getting created inside your ASP.NET Core project with certain class files.

You don’t need to change anything from these files. They are used by the dotnet-ef tool in the next step.

Now, issue the following command to apply the migration you just created.

dotnet ef database update

This command will create the database (if it doesn’t exist already) and create the table as per the EF Core model definition. If the database already exists, it will be updated (if needed) to reflect the EF Core model definition.

After executing this command successfully you should see MyNewDb database getting created as before.

Notice that this time __EFMigrationsHistory table is also added that is used internally by EF Core migrations.

Applying EF Core migrations programmatically

In the preceding section you created and applied the migrations using .NET Core CLI. You can also apply the created migrations via code. The following code shows how:

public void Configure(IApplicationBuilder app, 
IWebHostEnvironment env, AppDbContext db)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    db.Database.Migrate();

    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/
{action=Index}/{id?}");
    });
}

Here, you called the Migrate() method to apply the migration. The final outcome remains identical to the previous example.

Conclusion

Finally, at the end of this post we did a lot:

  • create a database structure
  • create a DbContext
  • add the database creation when the application starts
  • create the migration

If you want to know more about Entity Framework Core (EFCore), I have talked about Entity Framework in my previous posts:

One thought on “Create Database From Model Using EFCore

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.