Using EF Core in ASP.NET Core Web API for performing CRUD operations

Posted by: Mahesh Sabnis , on 2/27/2017, in Category Entity Framework
Views: 78827
Abstract: This article explains how to use Entity Framework (EF) Core in ASP.NET Core Web API for performing CRUD operations.

The Web API component of the application acts as an HTTP based interface which accepts HTTP requests from a third party client application and performs data operations. The following diagram tries to explain the possible architecture of this hypothetical application using Web API.

 

webapi-efcore-architecture

Figure 1: WebAPI with EFCore Application Architecture

This application can expose its business logic to the various client applications using Web API. Web API can effectively use the repositories to decouple the Business and Data Access Layers from the Web API Controller class. The Web API application can use inbuilt Dependency Injection (DI) to inject required dependencies in objects. For e.g. The Data Access can be registered in the DI and can be injected in the Business Layer, further the Business Layer can be registered in DI and injected in the Repository, and Repository in the Web API.

This article explains how to use EF Core in Web API for performing CRUD operations.

Entity Framework Core is a lightweight Data Access Technology provided on .NET Core. If you are new to EF Core, read https://www.dotnetcurry.com/entityframework/1347/entity-framework-ef-core-tutorial

Step 1: Open Visual Studio 2015 and create a new ASP.NET Core Web application as shown in the following image:

webapi-core-new-project

Name this application as WebApi_With_EFCore. Click on the OK Button, the following window will be displayed. Select Web API template from a list of ASP.NET Core templates.

webapi-template

Doing so will create a Web API application.

Step 2: The Application uses EF Core with a Sql Server database. This requires an installation of EF Core and Sql Server Packages.

Install-Package Microsoft.EntityFrameworkCore.SqlServer

Install-Package Microsoft.EntityFrameworkCore.Tools –Pre

These packages are used to provide EF Core database migration so that Database tables can be generated from the Entity.

Step 3: In the project, add a new folder named ’Models’. In this folder, add a new class file of the name ModelClasses.cs which will contain an Entity class as shown in the following code:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace WebApi_With_EFCore.Models
{
    public class Book
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }
        [Required (ErrorMessage ="Book Title Must be provided")]
        [StringLength(50, MinimumLength = 2)]
        public string BookTitle { get; set; }
        [Required(ErrorMessage = "Please provide Author Name")]
        [StringLength(100, MinimumLength = 2, ErrorMessage ="Length must be within 2 to 100 characters")]
        public string AuthorName { get; set; }
        [Required(ErrorMessage = "Publisher Name is must")]
        [StringLength(100, MinimumLength = 2,ErrorMessage ="Must be with 2 to 100 characters")]
        public string Publisher { get; set; }
        public string Genre { get; set; }
        [Required(ErrorMessage = "Book Price is must")]
        [DataType(DataType.Currency)]
        [Range(1, 999,ErrorMessage ="Must be with range from 1 to 999")]
        public int Price { get; set; }
    }
}

The above ‘Book’ class has an Id property which is applied with Key and DatabaseGenerated attributes. The DatabaseGeneratedOptions is set to None, which means that it will be used as an explicitly entered primary key. The other properties of the class are applied with validation attributes.

Step 4: In the Model folder, add a new class file of the name AppContext.cs. This class file contains the following code:

using Microsoft.EntityFrameworkCore;
namespace WebApi_With_EFCore.Models
{
 
    public class ApplicationContext : DbContext
    {
        public ApplicationContext(DbContextOptions opts):base(opts)
        {
        }
        public DbSet< Book > Books { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
        }
    }
}

The ApplicationContext class is derived from the DbContext class. The DbContext class is used to manage Database connection and transaction over the mapped table using DbSet. The parameterized constructor accepts DbContextOptions class which is used when the migration commands are executed.

Step 5: Open SQL Server and create a new database of the name WebApiEfCore using the following command:

Create database WebApiEfCore

Step 6: To define the connection string with the database so that it can be used by EF Core, add the following entry in the appsettings.json file.

"Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=.;Database=WebApiEfCore;Trusted_Connection=True;"
    }
}

Step 7: As per Figure 1, the application uses repositories to isolate the Data Access code from the Web Api controller class. To implement this isolation, add a new folder of name ‘Repositories’ in the application. Add a new class file of name DataAccessRepositories.cs in it which contains the following code:

using System.Collections.Generic;
using System.Linq;
using WebApi_With_EFCore.Models;

namespace WebApi_With_EFCore.Repositories
{
    public interface IDataAccess< TEntity,U > where TEntity : class
    {
        IEnumerable< TEntity > GetBooks();
        TEntity GetBook(U id);
        int AddBook(TEntity b);
        int UpdateBook(U id,TEntity b);
        int DeleteBook(U id); 
    }

    public class DataAccessRepository : IDataAccess< Book, int >
    {
        ApplicationContext ctx;
        public DataAccessRepository(ApplicationContext c)
        {
            ctx = c;
        }
        public int AddBook(Book b)
        {
            ctx.Books.Add(b);
            int res = ctx.SaveChanges();
            return res;
        }

        public int DeleteBook(int id)
        {
            int res = 0;
            var book = ctx.Books.FirstOrDefault(b => b.Id == id);
            if (book != null)
            {
                ctx.Books.Remove(book);
                res = ctx.SaveChanges();
            }
            return res;
        }

        public Book GetBook(int id)
        {
            var book = ctx.Books.FirstOrDefault(b=>b.Id==id);
            return book;
        }

        public IEnumerable< Book > GetBooks()
        {
            var books = ctx.Books.ToList();
            return books;
        }

        public int UpdateBook(int id,Book b)
        {
            int res = 0;
            var book = ctx.Books.Find(id);
            if (book != null)
            {
                book.BookTitle = b.BookTitle;
                book.AuthorName = b.AuthorName;
                book.Publisher = b.Publisher;
                book.Genre = b.Genre;
                book.Price = b.Price; 
               res = ctx.SaveChanges();
            }
            return res;
        }
    }
}

The above code contains an interface of the name ‘IDataAccess’. This is a generic interface which declares methods for performing CRUD operations. The interface is implemented by the DataAccessrepository class and implements all methods of an interface. The code uses the ApplicationContext class for performing database operations. The code is quite similar to EF 6.x code. The ‘ApplicationContext’ class is passed as dependency to the DataAccessRepository class.

So the question that arises is Where are the dependencies registered?

Registering all the required Dependencies

Step 8: To read the database connection string and to register all the required dependencies in DI, open Startup.cs and make the following changes in the ConfigureServices methods (highlighted):

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext< ApplicationContext >(opts=>
        opts.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
    services.AddSingleton(typeof(IDataAccess< Book, int >), typeof(DataAccessRepository));
    services.AddMvc();
}

The DI container registers DataAccessRepository class as a Singleton. The AddDbContext method uses the ApplicationContext class for injecting it in the DI container. This method further uses SQL Server connection string to map with the SQL Server database. Here the important point is that the AddDbContext uses a Lambda Expression which is the DbContextOptionsBuilder object. This object is further used when the migration commands are executed.

Step 9: Open the Package Manager Console using Tools > NuGet Package Manager > Package Manager Console and run the following commands for migration:

Add-Migration WebApi_With_EFCore.Models.ApplicationContext

Update-database

as shown in the following image:

commands-packages

These commands will add the Migrations folder in the project with classes containing code for Table generation. This will generate Books table in the WebApiEfCore database.

Step 10: In the Controllers folder, add a new Web Api Controller of the name BookAPIController as shown in the following image:

aspnet-core-webapi-controller

The BookAPIController class has the base class as a Controller, which is entirely different from the earlier version of Web API where the base class was ApiController class. This means that the MVC Controller and API Controllers has the same pipeline for request processing.

In this API controller, add the following code:

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using WebApi_With_EFCore.Models;
using WebApi_With_EFCore.Repositories;

namespace WebApi_With_EFCore.Controllers
{
    [Route("api/[controller]")]
    public class BookAPIController : Controller
    {
        IDataAccess

In the above code, the BookAPIController class contains a constructor with IDataAccess interface passed to it as dependency. This provides an instance of DataAccessRepository class to the controller class for performing CRUD operations.

Step 11: To launch the API, update the launchSettings.json file on the ‘Properties’ folder of the application (highlighted):

"profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "api/BookAPI",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
},

Build the project and make sure that it is error free.

Step 12: Run the application. This application can be tested using Fiddler (or any other REST client)

POST request

In Fiddler, add the URL and request body as show in the following image

post-request

This will add new record in the Books table in the WebApiEfCore database. When a GET Request is made using the browser, the response received is as follows:

get-request

Likewise, PUT and DELETE requested can also be tested.

Conclusion: Web API in ASP.NET Core effectively makes use of the DependencyInjection (DI) feature using which the Data Access code implemented using EF Core can be isolated from the action method of the Api Controller class.

Download the entire source code of this article (Github)

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Mahesh Sabnis is a DotNetCurry author and a Microsoft MVP having over two decades of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions), and Front-end technologies like Angular and React. Follow him on twitter @maheshdotnet or connect with him on LinkedIn


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!