Working With Data Using Entity Framework Core

Introduction

The purpose of this article is to tell you about how to work with databases in your ASP.NET applications, such as SQL Server, SQLite, and PostgreSQL and map objects to data with the help of an open-source framework called Entity Framework Core (EF Core).

Understanding EF Core

Entity Framework Core is the latest version of Entity Framework from Microsoft, which is an Object Relational Mapper (ORM). Object Relational Mapper is a technique that allows developers to work with data in an object-oriented way. ORMs are pre-written libraries of code that do lots of things, some of which are listed below.

  • It maps the Domain Model to database objects.
  • It generates the queries and executes them on its own.
  • Comes with Built-in Logging Feature (logs the entities).
  • Caching And Transaction management.

How to use EF Core

In order to work with EF Core for databases you can use two approaches, in accordance with the situation.

  • Code First
    When a database doesn't exist, we create a model, then EF Core creates a database with the defined fields.
     
  • Database First
    In this case, the database is already in place, so we design a model to match it.

Here we will start with Code First approach,

Installing EF Core

Step 1

Create a new project and choose ASP.NET Web App (Model-View-Controller)

Now we can install Entity Framework Core via one of the package management tool i.e Nuget Package Manager.

Note : Make sure you install the packages that are compatible with your .Net version.

Step 2

In order to do that, go to Tools>>NuGet Package Manager>>Manage NuGet Packages for Solution...

Step 3

Make sure the browser is selected at the top and search for "EntityFrameworkCore" and install the Package Microsoft.EntityFrameworkCore

Step 4

Select your project, click on the install and review all the changes made to your project, as well as accept the licenses attached to the various packages you are about to install.

Other Nuget Packages that are dependent are also installed.

In addition to EF Core, we will need the EF Core DB Provider, which is also included as NuGet package.

Step 5

Install NuGet package for the Database Provider that we want to access.Here we are using SQL SERVER as DB Provider so we will install "Microsoft.EntityFrameworkCore.SqlServer".

For different databases, there are different EF Core DB Providers available.

Together with the DB Provider we will need EF Core Tools which allows us to easily execute EF Core Commands. This tool will allow us to execute the EF Core Commands such as Migrations and Scaffolding directly from the Package Manager Console (PMC) or Using Dotnet CLI.

Step 6

Install NuGet Package for EF Core Tools "Microsoft.EntityFrameworkCore.Tools".

So as of now we are ready to go and use EF Core in our Application.

Working With EF Core

Step 1

Let’s Navigate to Model Folder and Create Class Named as Employee.cs

Step 2

We will add a few Properties to the Employee Model class that will acts as Column in our Database, so change the Employee class as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace EntityFrameworkDemo.Models
{
    public class Employee
    {
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Designation { get; set; }
        public int Age { get; set; }
        public decimal Salary { get; set; }
        public string FullName { get
            {
                return $"{FirstName} {LastName}";
            } 
        }
    }
}

Now, to interact with the database, we need to add the DbContext class, which is an integral part of the EntityFramework.

Some of the features that DBContext class provides:

  • Maintaining Database Integrity.
  • Configure the Model.
  • Execute CRUD operations on the database.
  • Transaction Management.

Step 3

In order to create DbContext Class we will add a Folder Named Data at root level and In that we’ll create a class named EmployeeContext.cs which we'll Inherit from DbContext Class, thus EmployeeContext class will becomes our Context class.

Step 4

Now create the Constructor of the EmployeeContext Class In Order to Tell the EF Core about the Connection String of the Database Provider.

In order to perform any useful task by the DbContext class, we need an instance of the DbContextOptions<TContext> class. The instance of the DbContextOptions carries all the required configuration information such as the Connection string, Database providers etc.

To pass the DbContextOptions instance we need to use the constructor of EmployeeContext class as shown below and In DbContextOptions<TContext>, TContext is a Generic type Context Class that we are Using.

An options is passed to the base class in order to tell the Base Constructor which Overload Constructor we are using.

using Microsoft.EntityFrameworkCore;

namespace EntityFrameworkDemo.Data
{
    public class EmployeeContext:DbContext
    {
        public EmployeeContext(DbContextOptions<EmployeeContext> options):base(options)
        {
	
        }
    }
}

Step 5

The entity framework core DbContext class includes a property i.e. DbSet<TEntity> for each entity in your application. Here in our working app there is one Model class that needs to map, i.e Employee class so add Employee Dbset to Create a Table in the Database.

namespace EntityFrameworkDemo.Data
{
    public class EmployeeContext:DbContext
    {
        public EmployeeContext(DbContextOptions<EmployeeContext> options):base(options)
        {
            
        }
        //The DbSet class represents an entity set that can be used for CRUD operations.
        public DbSet<Employee> Employee { get; set; }
    }
}

Step 6

Now, In order to connect to a database, we need the database connection string that we will define in the appsettings.json file.

Add the following JSON Pair to your appsetting.json

"ConnectionStrings": { "DefaultConnection": "Server = DESKTOP-OGH3VOT\MSSQLSERVER01; Database=EntityFrameWorkDB;
Trusted_Connection=True;MultipleActiveResultSets=true" }

Where server is used as DESKTOP-OGH3VOT\MSSQLSERVER01 which can be your SQL Server Name,

Database name is set to EntityFrameworkDB,

And Trusted_Connection and Multiple Query Fetching are set to true.

Step 7

Now in order to use this Connection String First we will read this Connection String and then Configure this with Context Class in by adding service to Startup.cs file.

services.AddDbContext<EmployeeContext>(option =>
            option.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")
            ));

Here Configuration Interface will read the data from appsettings.json file and GetConnectionString() method looks for a configuration value whose key is ConnectionStrings:<connection string name>.

We are now ready with the code. It is now time to add a Migration that informs the database about our Model Class and Configuration and creates a database accordingly.

But Before that what Migration Actually do?

  • Migration is the way to keep the Database always updated with the code that we write.
  • Whenever we make the changes to the Data Model Classes then we need to run the Migration in order to keep the Database updated about our changes.
  • EF Core Migrations are just the Command that we execute in Package Manager Console (PCM) or Dotnet CLI.
  • Here in our App we will be using the Package Manager Console (PCM).

Step 8

So Navigate to Tools>>NuGet Package Manager>>Package Manager Console

Package Manager Console will get opened in the footer where you can write the EF Core Migration Commands

Step 9

Now in Package Manager Console Execute the Following Command:

PM> add-migration Initial

So, this will Create<TimeStamp>_InitialNamed Migration Scripts in Migration Named Folder, as shown below.

Now after creating Migration Scripts it's time to update Database:

Step 10

In Package Manager Console execute the below command to update or create Database Schema.

PM> Update-Database

The Update command will create the database based on the context class and domain classes and the migration scripts.

As our Database Creates the _EFMigrationsHistory which keeps record of all the migrations that we perform.

Uptill now we have Created a Database that contains Table and Columns But it's still empty so we need to add some test data.

Initialize DB with Test Data

Step 1

In order to seed some data let's create SeedData named class in data folder.

And in that Class add the following test Data that we need to pass to our database,

namespace EntityFrameworkDemo.Data
{
    public class SeedData
    {
        public static void SeedDataDB(EmployeeContext context)
        {
            context.Database.EnsureCreated();    //It Ensures that Database For Context Already Exists

            if (context.Employee.Any())
            {
                return;   //Looks For Any Data in Employee DBSet
            }

            //Initialising Data
            var employees = new Employee[]
            {
                new Employee{FirstName="Bob",LastName="Wilson",Designation="Accounting",Age=32,Salary=50000},
                new Employee{FirstName="Mark",LastName="Mitchel",Designation="Human Resources",Age=26,Salary=48000},
                new Employee{FirstName="Parker",LastName="Chelse",Designation="Chartered Financial Analyst",Age=38,Salary=78000},
                new Employee{FirstName="George",LastName="Katie",Designation="Finance",Age=52,Salary=97000},
                new Employee{FirstName="Marie",LastName="Wood",Designation="Software Analyst",Age=31,Salary=65000},
                new Employee{FirstName="Lake",LastName="Marnus",Designation="Supply Chain and Logistics",Age=33,Salary=54000}
            };

            //Add Method Starts Tracking the Entities
            foreach(var employeeData in employees)
            {
                context.Employee.Add(employeeData);
            }
            context.SaveChanges();     //SaveChanges Method will makes all the Changes to Database
        }
    }
}

Step 2

Now we need to add this Data when we run our application so, in order to do that we need to configure the Database changes in the Main Method Located in Program.cs File

Navigate to Program.cs file and make following changes to it.

public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();
            CreateDbIfNotExists(host);
            host.Run();

        }
        public static void CreateDbIfNotExists(IHost host)
        {
            using(var scope = host.Services.CreateScope())  //IServiceScope Used for Scoped Services
            {
                var Services = scope.ServiceProvider;     //Resolve Dependency
                try
                {
                    var context = Services.GetRequiredService<EmployeeContext>();
                    SeedData.SeedDataDB(context);
                }
                catch (Exception ex)
                {
                    var logger = Services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An Error Occured Creating in DB");
                    throw;
                }
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

Here in the Program.cs file we have created an instance of the Context Class and then we have called SeedData.SeedDataDB method.

Whenever the app is run for the first time, the database is created and test data is loaded.

Step 3

Let's run the app,

Step 4

Now check for the Database and see that Database is loaded this is how we can load the test Data from Code to Database.

Conclusion

In this article we have configured our Model classes and Context Classes with the Database using EF Core. In future articles we will be performing CRUD Operation using EF Core and then also we will be adding some Pre-Built Validations and Custom Validations.

So, if you find this article helpful kindly share it with your friends.

You can find the source code on this Github Profile.