Create OData API with Entity FrameWork Code first Approach in ASP.NET Core

In this article, I will explain you how to setup OData API in .Net Core but before moving forward if you haven't read my article on Entity Framework Code First Approach in .Net Core then firstly read the article.

OData is an Open Data Protocol which gives the flexibility to your API's through the OData URL Conventions.

In our Part-2, We created the API project and used Entity Framework (Code First Approach). Now we need a mechanism to access the context from our API. Directly accessing the context methods from the API controller is a bad practice and we should avoid that. We will inject interface into our API Controller and API will communicate with the data context using the interface.

Now follow the steps to do this.

Step 1: Install OData Nuget package.
Go to NuGet package manager and install "Microsoft.AspNetCore.OData" package.


Step 2: Create a new folder under the Models folder and name it Repository and Create a new Interface under the repository folder and called it IStudentRepository.



using Microsoft.AspNet.OData;
using System;
using System.Linq;

namespace NET_Core_API.Models.Repository
{
   public interface IStudentRepository<TEntity> where TEntity : class
   { 
       IQueryable GetAll(); 
       TEntity Get(Guid id); 
       TEntity Add(TEntity entity); 
       void Update(TEntity entityToUpdate, Delta<TEntity> entity);
       void Delete(TEntity entity); 
    }
 }

Step 3: Now create a new folder under the Models folder, called it DataManager and then create a new class under this folder named it StudentManager. This class will implement IStudentRepository interface.




using Microsoft.AspNet.OData;
using NET_Core_API.Models.Repository;
using System;
using System.Linq;

namespace NET_Core_API.Models.DataManager
{
   public class StudentManager : IStudentRepository<Student> 
   { 
      readonly EntityContext _Context; 

      public StudentManager(EntityContext context) 
      {
           _Context = context; 
       }

       public IQueryable GetAll() 
      { 
         return _Context.Students;
       } 

       public Student Get(Guid id) 
      { 
          return _Context.Students.FirstOrDefault(e => e.ID == id); 
       } 

       public Student Add(Student entity) 
      { 
          _Context.Students.Add(entity);
          _Context.SaveChanges(); 
           return entity; 
       } 

         public void Update(Student studentToUpdate, Delta<Student> newStudent)
        {
            newStudent.Patch(studentToUpdate);
            _Context.SaveChanges();
        }

         public void Delete(Student student) 
        { 
            _Context.Students.Remove(student); 
            _Context.SaveChanges(); 
         }
      } 
}

GetAll(): Used to gets all the students from DB.

Get(): used to Get a specific student by passing GUID of student

Add():  used to create a new student in DB.

Delete(): used o delete the student from DB.

Update(): used to update student information.

Here we not directly accessing the context file in controller. Now this class(student class) which access the context file will perform all the CRUD operations instead of API controller.

Step 4: Go to Startup.cs file. Here we will configure the repository using dependency injection. This can be done in the ConfigureServices method in the Startup.cs.

services.AddScoped<IStudentRepository<Student>, StudentManager>();

Step 5: Create an API controller for Student.
Go to controller folder and create an API controller in it.





using System;
using System.Linq;
using Microsoft.AspNet.OData;
using Microsoft.AspNetCore.Mvc;
using NET_Core_API.Models;
using NET_Core_API.Models.Repository; 

namespace NET_Core_API.Controllers
{
    public class StudentController : ODataController
    {
       private readonly IStudentRepository<Student> _dataRepository; 

       public StudentController(IStudentRepository<Student> dataRepository) 
      { 
          _dataRepository = dataRepository; 
       } 

       // GET: api/Student 
       [HttpGet] 
       [EnableQuery]
       public IActionResult Get() 
       {
          IQueryable Students  = _dataRepository.GetAll(); 
          return Ok(Students); 
        } 

        // GET: api/Student/{GUID} 
        [HttpGet("{id}")] 
        [EnableQuery]
        public IActionResult Get(Guid id) 
       { 
          Student Student = _dataRepository.Get(id); 
          if (Student == null) 
         { 
            return NotFound("The Student record couldn't be found."); 
          } 
           return Ok(Student); 
        } 
     
         // POST: api/Student 
         [HttpPost] 
         public IActionResult Post([FromBody] Student Student) 
        { 
           if (Student == null) 
          { 
                return BadRequest("Student is null."); 
           } 
            Student student = _dataRepository.Add(Student); 
            return Ok(student); 
         } 

          // PUT: api/Student/{GUID} 
          [HttpPut("{id}")] 
           public IActionResult Put(Guid id, [FromBody] Delta<Student> Student)
          {
             if (Student == null)
             {
                return BadRequest("Student is null.");
             }
             Student StudentToUpdate = _dataRepository.Get(id);
           
             if (StudentToUpdate == null)
             {
                return NotFound("The Student record couldn't be found.");
             }
              _dataRepository.Update(StudentToUpdate, Student);
              return NoContent();
           }

             // DELETE: api/Student/{GUID} 
             [HttpDelete("{id}")] 
             public IActionResult Delete(Guid id) 
             { 
                 Student Student = _dataRepository.Get(id); 
                 if (Student == null) 
                 { 
                     return NotFound("The Student record couldn't be found.");
                  }
                    _dataRepository.Delete(Student); 
                     return NoContent(); 
               } 
            } 
       }

Step 6: Buid the EDM Model.
OData uses the Entity Data Model (EDM) to describe the structure of data. To build the EDM Model, add a static method in startup.cs file.
In this EDM Model, we defined one entity set which is student. you can define more sets according to your requirement.

 private static IEdmModel GetEdmModel() 
  { 
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Student>("Student");
            return builder.GetEdmModel();
   } 


Step 7: Register the OData Services.
The library provides an extension method called “AddOData()” to register the required OData services through the built-in dependency injection. Now add the following codes into “ConfigureServices” method in the “Startup” class:


services.AddOData();

and now we also need to change MVC() function service registration.
The EnableEndpointRouting option determines, routing should internally use endpoint-based logic. it's default value is true. Set the value to false. change the code as show in below snapshot.



  services.AddMvc(options =>
   {
          options.EnableEndpointRouting = false;
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Step 8: Register the OData Endpoint
Now We also need to add OData route to register the OData endpoint. We are going to add an OData route named “odata” with “odata” prefix to the MVC routes, and call the “GetEdmModel()” to bind the Edm model to the endpoint. Now add the following code into Configure method in stratup.cs file



   app.UseMvc(b =>
   {
                b.Select().Expand().Filter().OrderBy().MaxTop(1000).Count();
                b.MapODataServiceRoute("odata", "odata", GetEdmModel());
                b.EnableDependencyInjection();
   });


Now let's do the testing.
Now Hit the URL : https://localhost:44376/odata/student
If there is data then all the data will come but if there is no data it  will come like this.


Hope this will help you !!!




What is Data Seeding in .NET Core

Data seeding allows us to provide initial data during the creation of a database. Then, EF Core migrations will automatically determine what insert, update or delete operations need to be applied when upgrading the database to a new version of the model.
So let’s create some seed data now. For this, we need to override the OnModelCreating method in the Context class which we created in EF tutorial.

Copy the below code and paste it in context file. and change the code as per your need
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
      modelBuilder.Entity().HasData( 
               new Student 
              {
                    FirstName = "Student 1",
                    ID = new System.Guid("9b4cc8d2-78ab-47f0-41bc-08d6d9379d75") 
               },
               new Student  
              { 
                    FirstName = "Student 2", 
                    ID = new System.Guid("c13d7414-7d42-43c3-b934-08d6d9ed80a3")
              } 
            );
 }


Here we are creating two students in our database.

Now Run the command:
Add-Migration Name
and then update database by running following commands
Update-DataBase

it will update the database with the seed data which we provided

Limitations of seed data

  • The primary key value needs to be specified even if it's usually generated by the database. It will be used to detect data changes between migrations.
  • Previously seeded data will be removed if the primary key is changed in any way.
Therefore this feature is most useful for static data that's not expected to change outside of migrations and does not depend on anything else in the database, for example ZIP codes.

Create Web API with Entity FrameWork Code first Approach in ASP.NET Core - Part 3

This is the Part-3 of our article. If you haven't read part-2 yet then click Here to go.

In this article, I will explain you how to create a WEB API in .NET Core and also perform CRUD operations.


In Part-2, We created the API project and used Entity Framework (Code First Approach). Now we need a mechanism to access the context from our API. Directly accessing the context methods from the API controller is a bad practice and we should avoid that. We will inject interface into our API Controller and API will communicate with the data context using the interface. Now follow the steps to do this.

Step 1: Create a new folder under the Models folder and name it Repository and Create a new Interface under the repository folder and called it IStudentRepository.

Copy the below code and change this code as per your requirement:

using System;
using System.Linq;

namespace NET_Core_API.Models.Repository
{
   public interface IStudentRepository<TEntity> 
   { 
       IQueryable GetAll(); 
       TEntity Get(Guid id); 
       TEntity Add(TEntity entity); 
       void Update(TEntity entityToUpdate, TEntity entity); 
       void Delete(TEntity entity); 
    }
 }

Step 2: Now create a new folder under the Models folder, called it DataManager and then create a new class under this folder named it StudentManager. This class will implement IStudentRepository interface.


copy the below code and change it as per your requirement:
using NET_Core_API.Models.Repository;
using System;
using System.Linq;

namespace NET_Core_API.Models.DataManager
{
   public class StudentManager : IStudentRepository<Student> 
   { 
      readonly EntityContext _Context; 

      public StudentManager(EntityContext context) 
      {
           _Context = context; 
       }

       public IQueryable GetAll() 
      { 
         return _Context.Students;
       } 

       public Student Get(Guid id) 
      { 
          return _Context.Students.FirstOrDefault(e => e.ID == id); 
       } 

       public Student Add(Student entity) 
      { 
          _Context.Students.Add(entity);
          _Context.SaveChanges(); 
           return entity; 
       } 

       public void Update(Student studentToUpdate, Student newStudent) 
      {  
         studentToUpdate.FirstName = newStudent.FirstName; 
         studentToUpdate.LastName = newStudent.LastName; 
         _Context.SaveChanges(); 
        } 

         public void Delete(Student student) 
        { 
            _Context.Students.Remove(student); 
            _Context.SaveChanges(); 
         }
      } 
}

GetAll(): Used to gets all the students from DB.

Get(): used to Get a specific student by passing GUID of student

Add():  used to create a new student in DB.

Delete(): used o delete the student from DB.

Update(): used to update student information.


Here we not directly accessing the context file in controller. Now this class(student class) which access the context file will perform all the CRUD operations instead of API controller.

Strep 3: Go to Startup.cs file. Here we will configure the repository using dependency injection. This can be done in the ConfigureServices method in the Startup.cs.

services.AddScoped<IStudentRepository<Student>, StudentManager>();

Step 4: Now we will Create an API controller for Student.
Go to controller folder and create a API controller in it.





Now copy the blow code and change it as per your requirement.
using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using NET_Core_API.Models;
using NET_Core_API.Models.Repository; 

namespace NET_Core_API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StudentController : ControllerBase
    {
       private readonly IStudentRepository<Student> _dataRepository; 

       public StudentController(IStudentRepository<Student> dataRepository) 
      { 
          _dataRepository = dataRepository; 
       } 

       // GET: api/Student 
       [HttpGet] 
       public IActionResult Get() 
       {
          IQueryable Students  = _dataRepository.GetAll(); 
          return Ok(Students); 
        } 

        // GET: api/Student/{GUID} 
        [HttpGet("{id}")] 
        public IActionResult Get(Guid id) 
       { 
          Student Student = _dataRepository.Get(id); 
          if (Student == null) 
         { 
            return NotFound("The Student record couldn't be found."); 
          } 
           return Ok(Student); 
        } 
     
         // POST: api/Student 
         [HttpPost] 
         public IActionResult Post([FromBody] Student Student) 
        { 
           if (Student == null) 
          { 
                return BadRequest("Student is null."); 
           } 
            Student student = _dataRepository.Add(Student); 
            return Ok(student); 
         } 

          // PUT: api/Student/{GUID} 
          [HttpPut("{id}")] 
          public IActionResult Put(Guid id, [FromBody] Student Student) 
          { 
             if (Student == null) 
             { 
                return BadRequest("Student is null."); 
              } 
              Student StudentToUpdate = _dataRepository.Get(id); 
              if (StudentToUpdate == null) 
              { 
                 return NotFound("The Student record couldn't be found."); 
              } 
                 _dataRepository.Update(StudentToUpdate, Student); 
                 return NoContent(); 
             } 

             // DELETE: api/Student/{GUID} 
             [HttpDelete("{id}")] 
             public IActionResult Delete(Guid id) 
             { 
                 Student Student = _dataRepository.Get(id); 
                 if (Student == null) 
                 { 
                     return NotFound("The Student record couldn't be found.");
                  }
                    _dataRepository.Delete(Student); 
                     return NoContent(); 
               } 
            } 
       }

Now do your testing.

We have Successfully performed CRUD operations in .NET CORE API.

Create Web API with Entity FrameWork Code first Approach in ASP.NET Core - Part 2

This is the Part-2 of our article. If you haven't read part-1 yet then click Here to go.

In this article, I will explain you how to use Entity FrameWork with Code First Approach in our .NET Core project.


Step 1: Create a .NET Core project. 
Firstly open the visual studio and create a project in .NET Core. Here i am using VS19.

In the next window, Give the Name of your project. and then click on create button.


In the another next window, choose the type of project. Here i am selecting API. Also, from the drop-down choose ASP.NET Core 2.2. After all that, just click the Create button and then project will load.

Step 2: Add Connection String.
Go to appsettings.json file. and Add Database connection in this file as show in below.
modify the Connection String Property as per your need.
{
   "Logging": {
      "LogLevel": {
           "Default": "Warning"
      }
    },
  "ConnectionString": {
        "DB": "server=.;database=StudentDB;User ID=USER_NAME;password=PASSWORD;"      },
  "AllowedHosts": "*"
}
Step 3: Defining the Models.
Create a new folder Models within the root of the application. and add a new class Student.cs inside the Models folder.
Copy the below code and modify as per your need.
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace NET_Core_API.Models
{
       public class Student
      {
          [Key]
          [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
          public Guid ID { get; set; }
          public string FirstName { get; set; }
          public string LastName { get; set; }
      }
}

Step 4: Define Context File.
Now create CS EntityContext file in the project.
Copy the below code and paste it in context file. Change the code as per your need.
using Microsoft.EntityFrameworkCore;
using NET_Core_API.Models;

namespace NET_Core_API
{
     public class EntityContext : DbContext
     {
        public EntityContext(DbContextOptions options)
             : base(options)
       {
       }
        public DbSet Students { get; set; } 
    }
}

Step 5: Register the context file.
Now go to Startup.cs file and register our context in the Startup.cs file.
Copy the below code and paste it in ConfigureServices function.
services.AddDbContext(opts => opts.UseSqlServer(Configuration["ConnectionString:DB"]));

Step 5: Install EFCore.SQL.
Go to NuGet package manager and install Microsoft.EntityFrameworkCore.SqlServer package.


Step 6: Create DataBase
Go to NuGet console and run the command
Add-Migration NAME


Now let’s apply these changes to the database.
Run the following command
Update-Database


This will update the database based on our models.

Now go to database and check, it will create the DB.



Create Web API with Entity FrameWork Code first Approach in ASP.NET Core - Part 1

Hello folks, I am writing an article on WEB API with Entity FrameWork in .NET Core.

This article is divided into 3 parts:




So this is the 1st article where i will explain about .NET Core, Entity-framework

What is .NET Core :

.NET Core is a cross platform, open source re-implementation of the .NET Framework. It is actively maintained by Microsoft. It is cross-platform framework to build applications for all operating system including Windows, Mac, and Linux.

What is Entity FrameWork :

Prior to .NET 3.5, developers often used to write ADO.NET code to save or retrieve application data from the underlying database. We used to open a connection to the database, create a DataSet  to fetch or submit the data to the database, convert data from the DataSet to .NET objects or vice-versa to apply business rules. This was a cumbersome and error prone process. Microsoft has provided a framework called "Entity Framework" to automate all these database related activities for your application. 
Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects.

Entity FrameWork Core : 

It is the new version of Entity Framework after EF 6.x. It is open-source, lightweight, extensible and a cross-platform version of Entity Framework data access technology. It is an enhancement to ADO.NET that gives developers an automated mechanism for accessing & storing the data in the database. 
EF Core supports two development approaches 1) Code-First 2) Database-First.

In the Code-First Approach, Entity Framework Core API creates the database and tables using migration based on the conventions and configuration provided in your domain classes. This approach is useful in Domain Driven Design (DDD).
In the simple language, we can say it create our DataBase from class using commands.
In the Database-First Approach, Entity Framework Core API creates the domain and context classes based on your existing database using Entity Framework Core commands. This has limited support in Entity Framework Core as it does not support visual designer or wizard.
In the simple language,we can say it create classes from our DB.


Prerequisites:
For this series you will need:
  • Sql Server (SSMS)
  • .NET SDK
  • Visual Studio 2017 or Visual Studio 2019.