Introduction
In this article, we will discuss the Code-First Approach in Entity Framework Core using ASP.NET Core 2.1. Entity Framework Core is the new technology introduced by Microsoft along with the introduction of ASP.NET Core. As per Microsoft, ASP.NETsp.Net Core is the next generation of the Asp.Net technology. In the earlier version of Asp.Net; i.e. Asp.Net 3.5, we normally used the ADO.Net to communicate with the SQL based database for storing data or fetching the data. In this process, we normally used the dataset object to retrieve the data from the database and then we converted the dataset objects to the .Net or C# class objects or vice-versa to implement the business logic. Ultimately it is not a short process and there is a high chance of making a mistake in this process.
So, in 2008, Microsoft first introduced a technology called Entity Framework along with Asp.Net 3.5 Service Pack1 which basically automates the entire process of database connection and data retrieval steps. But in spite of that release, Entity Framework became the main topic of discussion in 2011 when Microsoft introduced Entity Framework along with the Code First Approach in the Asp.Net 4.1 version. The code first approach is mainly useful when we follow the Domain Driven Design or Development. In the process, we mainly focus on the domain structure of the application and start creating the classes or models for our domain entity rather than designing the database or its tables first. The entity classes or models which we create for designing the domain application will be mapped with the table objects of the database. The below image demonstrates the code first approach.
So, the above image shows that Entity Framework API will create the database or tables on the basis of the defined domain or model classes. So, in the Code First Approach, we always need to start the coding using C# in the case of Asp.Net. So, in the case of Code First Approach, we need to follow the below steps sequentially,
- Create or Modify the Entity Class
- Configure these class using Data Annotations or Fluent API
- Create the Database or Tables using Migration Command
- Design the Views on the basis of Model Class
Below the diagrams demonstrate the workflow of the Code First Approach.
So, in the Asp.net Core or Entity Framework Core, we can also perform the same code first approach for developing our applications. Basically, Entity Framework or Entity Framework core is an Open Source based Framework which totally depends on the Object Relational Mapping or ORM Model. This framework basically reduced the developer’s effort for establishing the database connection or save data to the database or retrieve data from the database. So, in this article, we will discuss how we can create a CRUD based operation in Asp.Net Core using Entity Framework Core in Code First Approach.
Perquisite- Visual Studio 2017 (Any Edition – Community / Professional / Enterprise)
- Microsoft SQL Server 2008 or above.
- .Net Core 2.1 SDK or Later Version
Steps to Create Model Class
Step 1
Now, we first want to create the domain classes for the Applications. So, we open the Visual Studio 2017 and Create a Blank Solution as below,
Step 2
Now, a .Net Class Library Project in this Blank Solution for creating our Model Class in Solutions.
Step 3
Now, we need to install the Entity Framework Related Packages in this .Net Class Library Project. For that open the Nuget Package Manager from Tools Menu and Install the Below Packages using Nuget Package Manager.
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.SqlServer
- Microsoft.EntityFrameworkCore.Tools
These three packages are responsible for creating the migration script as per the entity models and creating objects in the database & tables.
Step 4
Now, create two classes named Department and Designation, which are our model classes as below,
Department.cs
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
-
- namespace DataContextLayer.Models
- {
- public class Department
- {
- public int DepartmentId { get; set; }
-
- public string DepartmentCode { get; set; }
-
- public string DepartmentName { get; set; }
-
- public string Description { get; set; }
- }
- }
Designation.cs
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
-
- namespace DataContextLayer.Models
- {
- public class Designation
- {
- public int DesignationId { get; set; }
-
- public string DesignationCode { get; set; }
-
- public string DesignationName { get; set; }
-
- public int DepartmentId { get; set; }
-
- public string DepartmentName { get; set; }
-
- }
- }
Steps to Apply Data Annotations
Step 1
Now, the classes which we create above are independent and do not have any relation between them. So, first we apply the data annotation in the department class as below.
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
-
- namespace DataContextLayer.Models
- {
- [Table("Department", Schema = "dbo")]
- public class Department
- {
- [Key]
- [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- [Display(Name = "Department Id")]
- public int DepartmentId { get; set; }
-
- [Required]
- [Column(TypeName = "varchar(20)")]
- [Display(Name = "Department Code")]
- public string DepartmentCode { get; set; }
-
- [Required]
- [Column(TypeName = "varchar(100)")]
- [Display(Name = "Department Description")]
- public string DepartmentName { get; set; }
-
- [Column(TypeName = "varchar(100)")]
- public string Description { get; set; }
- }
- }
Step 2
Now, we will apply the data annotations in the designation class also. In the Designation class, we have an attribute called DepartmentId which needs to be implemented as a Foreign key in the Database Tables concept. That’s why we implement the Foreign Key annotation in the Designation class as below.
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
-
- namespace DataContextLayer.Models
- {
- [Table("Designation", Schema = "dbo")]
- public class Designation
- {
- [Key]
- [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- public int DesignationId { get; set; }
-
- [Required]
- [Column(TypeName = "varchar(20)")]
- [Display(Name = "Designation Code")]
- public string DesignationCode { get; set; }
-
- [Required]
- [Column(TypeName = "varchar(100)")]
- [Display(Name = "Designation Name")]
- public string DesignationName { get; set; }
-
- [ForeignKey("DepartmentInfo")]
- [Required]
- public int DepartmentId { get; set; }
-
- [NotMapped]
- public string DepartmentName { get; set; }
-
- public virtual Department DepartmentInfo { get; set; }
- }
- }
Step 3
Also, we marked the DepartmentDesc as NotMapped since we did not want to create any column in the designation table with such a name. We will use the attribute simply for displaying the data in the view.
Step 4
Now, we create another class named EFDataContext where we inherit the DBContext class of the Entity Framework and Create the DBSet objects of Department and Designation Class. Also, we override the OnConfiguring() method to provide the database connection details where we need to create the database as per the Entity model class.
- using DataContextLayer.Models;
- using Microsoft.EntityFrameworkCore;
- using System;
- using System.Collections.Generic;
- using System.Data.SqlClient;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace DataContextLayer.DataContext
- {
- public class EFDataContext : DbContext
- {
- public DbSet<Department> Departments { get; set; }
-
- public DbSet<Designation> Designations { get; set; }
-
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseSqlServer(@"data source=serverName; initial catalog=TestDB;persist security info=True;user id=sa");
- }
- }
- }
Steps to Automate Migration
Step 1
Now, it's time to automate the migration from our entity class to the database objects. So for this, open the Nuget Package Manager Console Under the Nuget Package Manager Menu and run the command add-migration in the console. It will create the migration files on the basis of the Entity Model class as we defined.
The above command creates a Migration file as the below image shown and also create a Migration to the store that file. Now we need to run this migration file to create or update the database.
For creating or updating the database, run the command Update-Database in the console and then check the SQL server for the database and tables objects.
Now check the database Object Explorer,
Now, we will create views from where we can create or edit or view Department or Designation Data. For this purpose, we need to add another project in the Solution Web Application Projects as the below image.
Now Click on the Ok Button and then select Model View Controller Temlpate in the Template window and click on the OK Button.
Now, Select the Controller Folder and Click on Add Controller Options,
On clicking on Add Button, it will create an Empty Controller with the Index Action Method. Now Right Click on the Index() and Click on Add View Options and then select the options as below,
On Clicking on Add Button, it will automatically scaffold the list view page of the department. Now, add another action method named create() in the department controller and then again click on the add view options to the view for creating the view for the department insert.
Below is the complete code of the DepartmentController, Department List View and Deparment Create View. We also use the same Create view for editing the department. For this we will change a small part in the view to fit the requirements.
DepartmentController.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using DataContextLayer.DataContext;
- using DataContextLayer.Models;
- using Microsoft.AspNetCore.Mvc;
-
- namespace WebAppLayer.Controllers
- {
- public class DepartmentsController : Controller
- {
-
- EFDataContext _dbContext = new EFDataContext();
-
- public IActionResult Index()
- {
- List<Department> data = this._dbContext.Departments.ToList();
- return View(data);
- }
-
- public IActionResult Create()
- {
- return View();
- }
-
- [HttpPost]
- public IActionResult Create(Department model)
- {
- ModelState.Remove("DepartmentId");
- if (ModelState.IsValid)
- {
- _dbContext.Departments.Add(model);
- _dbContext.SaveChanges();
- return RedirectToAction("Index");
- }
- return View();
- }
-
- public IActionResult Edit(int id)
- {
- Department data = _dbContext.Departments.Where(p => p.DepartmentId == id).FirstOrDefault();
- return View("Create", data);
- }
-
- [HttpPost]
- public IActionResult Edit(Department model)
- {
- ModelState.Remove("DepartmentId");
- if (ModelState.IsValid)
- {
- _dbContext.Departments.Update(model);
- _dbContext.SaveChanges();
- return RedirectToAction("Index");
- }
- return View("Create", model);
- }
-
- public IActionResult Delete(int id)
- {
- Department data = _dbContext.Departments.Where(p => p.DepartmentId == id).FirstOrDefault();
- if (data != null)
- {
- _dbContext.Departments.Remove(data);
- _dbContext.SaveChanges();
- }
- return RedirectToAction("Index");
- }
- }
- }
Index.cshtml (Department)
- @model IEnumerable<DataContextLayer.Models.Department>
-
- @{
- ViewData["Title"] = "Index";
- }
-
- <strong>Index</strong>
-
- <p>
- <a asp-action="Create">Create New</a>
- </p>
- <table class="table">
- <thead>
- <tr>
- <th>
- @Html.DisplayNameFor(model => model.DepartmentId)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.DepartmentCode)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.DepartmentName)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Description)
- </th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- @foreach (var item in Model) {
- <tr>
- <td>
- @Html.DisplayFor(modelItem => item.DepartmentId)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.DepartmentCode)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.DepartmentName)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Description)
- </td>
- <td>
- @Html.ActionLink("Edit", "Edit", new { id = item.DepartmentId }) |
- @Html.ActionLink("Delete", "Delete", new { id = item.DepartmentId }, new { onclick = "return confirm('Are you sure to delete?')" })
- </td>
- </tr>
- }
- </tbody>
- </table>
Creatte.cshtml (Department)
- @model DataContextLayer.Models.Department
-
- @{
- ViewData["Title"] = Model != null ? "Edit" : "Create";
- }
-
- <strong>@ViewData["Title"]</strong>
-
- <h4>Department</h4>
- <hr />
- <div class="row">
- <div class="col-md-4">
- <form asp-action="@ViewData["Title"]">
- <div asp-validation-summary="ModelOnly" class="text-danger"></div>
- <input type="hidden" asp-for="DepartmentId" class="form-control" />
- <div class="form-group">
- <label asp-for="DepartmentCode" class="control-label"></label>
- <input asp-for="DepartmentCode" class="form-control" />
- <span asp-validation-for="DepartmentCode" class="text-danger"></span>
- </div>
- <div class="form-group">
- <label asp-for="DepartmentName" class="control-label"></label>
- <input asp-for="DepartmentName" class="form-control" />
- <span asp-validation-for="DepartmentName" class="text-danger"></span>
- </div>
- <div class="form-group">
- <label asp-for="Description" class="control-label"></label>
- <input asp-for="Description" class="form-control" />
- <span asp-validation-for="Description" class="text-danger"></span>
- </div>
- <div class="form-group">
- <input type="submit" value="Save" class="btn btn-default" />
- </div>
- </form>
- </div>
- </div>
-
- <div>
- <a asp-action="Index">Back to List</a>
- </div>
-
- @section Scripts {
- @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
- }
Similarly, we need to create the Designation Controller and its related view for displaying or creating or editing the data.
DesignationController.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using DataContextLayer.DataContext;
- using DataContextLayer.Models;
- using Microsoft.AspNetCore.Mvc;
-
- namespace WebAppLayer.Controllers
- {
- public class DesignationsController : Controller
- {
- EFDataContext _dbContext = new EFDataContext();
-
- public IActionResult Index()
- {
-
-
- var data = (from dept in _dbContext.Departments
- join desig in _dbContext.Designations
- on dept.DepartmentId equals desig.DepartmentId
- select new Designation
- {
- DesignationId = desig.DesignationId,
- DesignationCode = desig.DesignationCode,
- DesignationName = desig.DesignationName,
- DepartmentId = desig.DepartmentId,
- DepartmentName = dept.DepartmentName
- }).ToList();
-
- return View(data);
- }
-
- public IActionResult Create()
- {
- ViewBag.Departments = _dbContext.Departments.ToList();
- return View();
- }
-
- [HttpPost]
- public IActionResult Create(Designation model)
- {
- ModelState.Remove("DesignationId");
- if (ModelState.IsValid)
- {
- _dbContext.Designations.Add(model);
- _dbContext.SaveChanges();
- return RedirectToAction("Index");
- }
- ViewBag.Departments = _dbContext.Departments.ToList();
- return View();
- }
-
- public IActionResult Edit(int id)
- {
- Designation data = _dbContext.Designations.Where(p => p.DesignationId == id).FirstOrDefault();
- ViewBag.Departments = _dbContext.Departments.ToList();
- return View("Create", data);
- }
-
- [HttpPost]
- public IActionResult Edit(Designation model)
- {
- ModelState.Remove("DesignationId");
- if (ModelState.IsValid)
- {
- _dbContext.Designations.Update(model);
- _dbContext.SaveChanges();
- return RedirectToAction("Index");
- }
- ViewBag.Departments = _dbContext.Departments.ToList();
- return View("Create", model);
- }
-
- public IActionResult Delete(int id)
- {
- Designation data = _dbContext.Designations.Where(p => p.DesignationId == id).FirstOrDefault();
- if (data != null)
- {
- _dbContext.Designations.Remove(data);
- _dbContext.SaveChanges();
- }
- return RedirectToAction("Index");
- }
- }
- }
Index.cshtml (Designation)
- @model IEnumerable<DataContextLayer.Models.Designation>
-
- @{
- ViewData["Title"] = "Index";
- }
-
- <strong>Index</strong>
-
- <p>
- <a asp-action="Create">Create New</a>
- </p>
- <table class="table">
- <thead>
- <tr>
- <th>
- @Html.DisplayNameFor(model => model.DesignationId)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.DesignationCode)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.DesignationName)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.DepartmentName)
- </th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- @foreach (var item in Model) {
- <tr>
- <td>
- @Html.DisplayFor(modelItem => item.DesignationId)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.DesignationCode)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.DesignationName)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.DepartmentName)
- </td>
- <td>
- @Html.ActionLink("Edit", "Edit", new { id=item.DesignationId }) |
- @Html.ActionLink("Delete", "Delete", new { id=item.DesignationId })
- </td>
- </tr>
- }
- </tbody>
- </table>
create.cshtml
- @model DataContextLayer.Models.Designation
-
- @{
- ViewData["Title"] = Model != null ? "Edit" : "Create";
- }
-
- <strong>@ViewData["Title"]</strong>
-
- <h4>Designation</h4>
- <hr />
- <div class="row">
- <div class="col-md-4">
- <form asp-action="@ViewData["Title"]">
- <div asp-validation-summary="ModelOnly" class="text-danger"></div>
- <input type="hidden" asp-for="DesignationId" class="form-control" />
- <div class="form-group">
- <label asp-for="DesignationCode" class="control-label"></label>
- <input asp-for="DesignationCode" class="form-control" />
- <span asp-validation-for="DesignationCode" class="text-danger"></span>
- </div>
- <div class="form-group">
- <label asp-for="DesignationName" class="control-label"></label>
- <input asp-for="DesignationName" class="form-control" />
- <span asp-validation-for="DesignationName" class="text-danger"></span>
- </div>
-
- <div class="form-group">
- <label asp-for="DepartmentId" class="control-label"></label>
- <select asp-for="DepartmentId" asp-items="@(new SelectList(ViewBag.Departments,"DepartmentId","DepartmentName"))" class="form-control">
- <option value="">--Select--</option>
- </select>
- <span asp-validation-for="DepartmentId" class="text-danger"></span>
- </div>
- <div class="form-group">
- <input type="submit" value="Save" class="btn btn-default" />
- </div>
- </form>
- </div>
- </div>
-
- <div>
- <a asp-action="Index">Back to List</a>
- </div>
-
- @section Scripts {
- @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
- } N
Now, run the application in the browser and it will show you the below result,
Conclusion
So, in this article we will discuss about the basic concept of the Code First Approach and also discuss how to implement this code first approach in the Entity Framework Core. For any further query or clarification, ping me.