Entity Framework (EF) Core is the latest version of Entity Framework from Microsoft. It is an open-source, lightweight, extensible, and cross-platform version of Entity Framework. It runs on Windows, Mac, and Linux.
Entity Framework is an object/relational mapping (O/RM) framework. It is an enhancement of ADO.NET that gives developers an automated mechanism for accessing and storing data in a database.
Every web app needs a data source, and EF Core is a great way to interact with a SQL database. So, let’s walk through the process of adding EF Core to a Blazor app.
In the past, JavaScript was the only programming language available for client-side web applications. Now, we have different choices of client frameworks, such as Angular, React, and others, but in the end, it always runs as JavaScript in the browser.
Recently, WebAssembly (wasm) changes all of that.
According to the WebAssembly.org website:
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for the compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
Blazor is a UI web framework built on .NET. It runs on browsers using WebAssembly, and it provides a choice of client-side programming language—C# rather than JavaScript.
Now, we will see how to do CRUD operations using a Blazor app with EF Core.
In this blog, I am using Visual Studio to build the application. I have the following software installed:
Let’s create a database on our local SQL Server.
Create Table Employee( EmployeeId BigInt Identity(1,1) Primary Key, Name Varchar(100) Not Null, Designation Varchar(100), Email Varchar(20), Location Varchar(50) Not Null, PhoneNumber bigint Not Null)
Follow these steps to create a Blazor application:
Now, we have three project files created inside this solution:
The following NuGet packages should be added to work with the SQL Server database and scaffolding. Run these commands in the Package Manager Console:
Let’s create entity and context classes for the Management database in the local SQL server.
Run the following scaffold command in the Package Manager Console to reverse engineer the database to create database context and entity classes from any tables. The Scaffold command will create a class for the tables that have a primary key.
Scaffold-DbContext “Server=.\\;Database=Management;Integrated Security=True” Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
After running the command, the Employee class and Management Context class will be created as shown in the following screenshot.
In the auto-generated EmployeeContext class file, the database credentials you can see are hard coded in the OnConfiguring method. It is not a good practice to have SQL Server credentials in C# class, considering the security issues. So, remove the following OnConfiguring method and parameterless constructor from context file.
Right-click the BlazorCrud.Server and then select Add >> New Folder and named as DataAccess.
Create a class EmployeAccessLayer in DataAccess Folder. This class will handle the CRUD related DB operations. Paste the following code into it.
using BlazorCrud.Server.Models; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace BlazorCrud.Server.DataAccess { public interface IEmployeAccessLayer { IEnumerable GetAllEmployees(); void AddEmployee(Employee employee); void UpdateEmployee(Employee employee); Employee GetEmployeeData(long id); void DeleteEmployee(long id); } public class EmployeAccessLayer : IEmployeAccessLayer { private ManagementContext _context; public EmployeAccessLayer(ManagementContext context) { _context = context; } //To Get all employees details public IEnumerable GetAllEmployees() { try { return _context.Employee.ToList(); } catch(Exception ex) { throw; } } //To Add new employee record public void AddEmployee(Employee employee) { try { _context.Employee.Add(employee); _context.SaveChanges(); } catch { throw; } } //To Update the records of a particluar employee public void UpdateEmployee(Employee employee) { try { _context.Entry(employee).State = EntityState.Modified; _context.SaveChanges(); } catch { throw; } } //Get the details of a particular employee public Employee GetEmployeeData(long id) { try { Employee employee = _context.Employee.Find(id); return employee; } catch { throw; } } //To Delete the record of a particular employee public void DeleteEmployee(long id) { try { Employee emp = _context.Employee.Find(id); _context.Employee.Remove(emp); _context.SaveChanges(); } catch { throw; } } } }
Now, we will modify the controller actions to perform CRUD operations.
Step 1: Inject IEmployeeAccessLayer with the employee controller’s constructor, as shown in the following screenshot.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using BlazorCrud.Server.DataAccess; using BlazorCrud.Server.Models; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace BlazorCrud.Server.Controllers { [ApiController] public class EmployeeController : ControllerBase { IEmployeAccessLayer _employee; public EmployeeController(IEmployeAccessLayer employee) { _employee = employee; } [HttpGet] [Route("api/Employee/Index")] public IEnumerable<Employee> Index() { return _employee.GetAllEmployees(); } [HttpPost] [Route("api/Employee/Create")] public void Create([FromBody] Employee employee) { if (ModelState.IsValid) this._employee.AddEmployee(employee); } [HttpGet] [Route("api/Employee/Details/{id}")] public Employee Details(int id) { return _employee.GetEmployeeData(id); } [HttpPut] [Route("api/Employee/Edit")] public void Edit([FromBody]Employee employee) { if (ModelState.IsValid) this._employee.UpdateEmployee(employee); } [HttpDelete] [Route("api/Employee/Delete/{id}")] public void Delete(int id) { _employee.DeleteEmployee(id); } } }
The actions and their purposes are explained:
Index: Returns all the employees from the database and returns to view.
Details: Returns the employee details from the employee table by employee id. If the employee is not found, then it will return a Not Found result.
Create: Accepts employee details as input and creates a new employee in the database.
Edit: Accepts the employee ID and details as input and, if the employee is found, then it updates the new details in the database.
Delete: Gets the employee ID as input, requests confirmation, and deletes that employee from database.
Let’s see how to create Razor pages for CRUD operations.
Let’s add the code in the Razor files and web API controller to display, create, update, and delete.
An HTTP GET request can be sent to get a resource from the API using the GetJsonAsync() method provided by the HttpClient class.
Open GetEmployee.razor and add the following code to it.
@page "/employee" @inject HttpClient Http <h1>Employee Data</h1> <p> <a href="/employee/add">Create</a> </p> @if (empList == null) { <p><em>Loading...</em></p> } else { <table class='table'> <thead> <tr> <th>ID</th> <th>Name</th> <th>Designation</th> <th>Email</th> <th>Location</th> <th>Phone</th> <th>Action</th> </tr> </thead> <tbody> @foreach (var emp in empList) { <tr> <td>@emp.EmployeeId</td> <td>@emp.Name</td> <td>@emp.Designation</td> <td>@emp.Email</td> <td>@emp.Location</td> <td>@emp.PhoneNumber</td> <td> <a href='/employee/edit/@emp.EmployeeId'>Edit</a> | <a href='/employee/delete/@emp.EmployeeId'>Delete</a> </td> </tr> } </tbody> </table> } @code { Employee[] empList; protected override async Task OnInitializedAsync() { empList = await Http.GetJsonAsync<Employee[]>("/api/Employee/Index"); } }
[HttpGet] [Route("api/Employee/Index")] public IEnumerable Index() { return _employee.GetAllEmployees(); }
An HTTP POST request can be sent to add new data in the API using the SendJsonAsync() method provided by the HttpClient class.
Open AddEmployee.razor and add the following code to it.
@page "/employee/add" @inject HttpClient Http @inject Microsoft.AspNetCore.Components.NavigationManager navigation <h1>Create</h1> <hr /> <div class="row"> <div class="col-md-4"> <form> <div class="form-group"> <label for="Name" class="control-label">Name</label> <input for="Name" class="form-control" @bind="@emp.Name" /> </div> <div class="form-group"> <label asp-for="Designation" class="control-label">Designation</label> <input for="Designation" class="form-control" @bind="@emp.Designation" /> </div> <div class="form-group"> <label asp-for="Email" class="control-label">Email</label> <input asp-for="Email" class="form-control" @bind="emp.Email" /> </div> <div class="form-group"> <label asp-for="Location" class="control-label">Location</label> <input asp-for="Location" class="form-control" @bind="@emp.Location" /> </div> <div class="form-group"> <label asp-for="Phone" class="control-label">Phone</label> <input asp-for="Phone" class="form-control" @bind="emp.PhoneNumber" /> </div> <div class="form-group"> <button type="submit" class="btn btn-default" @>[HttpPost] [Route("api/Employee/Create")] public void Create([FromBody] Employee employee) { if (ModelState.IsValid) this.employee.AddEmployee(employee); }Update
The HTTP PUT method is used to completely replace a resource on the server. We can use the HttpClient to send a PUT request to an API using the SendJsonAsync() method.
Open EditEmployee.razor and add the following code to it.
@page "/employee/edit/{empID}" @inject HttpClient Http @inject Microsoft.AspNetCore.Components.NavigationManager navigation <h2>Edit</h2> <h4>Employees</h4> <hr /> <div class="row"> <div class="col-md-4"> <form> <div class="form-group"> <label for="Name" class="control-label">Name</label> <input for="Name" class="form-control" @bind="@emp.Name" /> </div> <div class="form-group"> <label asp-for="Designation" class="control-label">Designation</label> <input for="Designation" class="form-control" @bind="@emp.Designation" /> </div> <div class="form-group"> <label asp-for="Email" class="control-label">Email</label> <input asp-for="Email" class="form-control" @bind="@emp.Email" /> </div> <div class="form-group"> <label asp-for="Location" class="control-label">Location</label> <input asp-for="Location" class="form-control" @bind="@emp.Location" /> </div> <div class=" form-group"> <label asp-for="Phone" class="control-label">Phone</label> <input asp-for="Phone" class="form-control" @bind="@emp.PhoneNumber" /> </div> <div class="form-group"> <input type="submit" value="Save" @>[HttpPut] [Route("api/Employee/Edit")] public void Edit([FromBody]Employee employee) { if (ModelState.IsValid) this.employee.UpdateEmployee(employee); }Delete
An HTTP DELETE request can be sent to delete a resource from the server using the DeleteAsync() method provided by the HttpClient class.
Open DeleteEmployee.razor and add the following code in it.
@page "/employee/delete/{empId}" @inject HttpClient Http @inject Microsoft.AspNetCore.Components.NavigationManager navigation <h2>Delete</h2> <h3>Are you sure you want to delete employee with id : @empId</h3> <br /> <div class="col-md-4"> <table class="table"> <tr> <td>Name</td> <td>@emp.Name</td> </tr> <tr> <td>Designation</td> <td>@emp.Designation</td> </tr> <tr> <td>Email</td> <td>@emp.Email</td> </tr> <tr> <td>Location</td> <td>@emp.Location</td> </tr> <tr> <td>Phone</td> <td>@emp.PhoneNumber</td> </tr> </table> <div class="form-group"> <input type="submit" value="Delete" @>[HttpDelete] [Route("api/Employee/Delete/{id}")] public void Delete(int id) { employee.DeleteEmployee(id); }Run the application
- Click Run to view the application. The page will be opened in a new browser window.
- Click Employee in the navigation menu. This will direct you to the Employee page. Initially, this page will be empty.
- Click the Create link to create a new employee entry. Enter the employee details and click Save.
- Now, the created employee details are displayed as shown in the following screenshot.
- Click Edit to update the employee details.
- Click Delete to delete a product. A confirmation alert will appear before it is deleted from the database.
You can also fork this application on GitHub.
Conclusion
In this blog, we have learned how to create a Blazor application and perform basic CRUD operations using Entity framework Core 3.0.
Syncfusion provides more than 65 high-performance, lightweight, modular, and responsive Blazor UI controls such as DataGrid, Charts, and Scheduler to ease the work of developers.
If you have any questions, please let us know in the comments section below. You can also contact us through our support forum, Direct-Trac, or feedback portal. We are always happy to assist you!