Project Overview
Tech Stack
Frontend: Angular 17+
Backend: ASP.NET Core 7 Web API
Database: SQL Server
ORM: Entity Framework Core
Features
Display employees in a table
Add, update, delete employees (CRUD)
Paging
Sorting by columns
Filtering/searching
Step 1: Database Setup (SQL Server)
Create a database called EmployeeDb. Then create a table:
CREATE TABLE Employees (
Id INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(100),
Email NVARCHAR(100),
Department NVARCHAR(50)
);
Insert some sample data:
INSERT INTO Employees (Name, Email, Department)
VALUES
('Alice','[email protected]','HR'),
('Bob','[email protected]','IT'),
('Charlie','[email protected]','Finance'),
('David','[email protected]','IT'),
('Eva','[email protected]','HR');
Step 2: ASP.NET Core API Setup
2.1 Create the Web API Project
dotnet new webapi -n EmployeeApi
cd EmployeeApi
2.2 Install EF Core Packages
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
2.3 Create Employee Model
Models/Employee.cs:
namespace EmployeeApi.Models
{
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Department { get; set; }
}
}
2.4 Create DbContext
Data/AppDbContext.cs:
using EmployeeApi.Models;
using Microsoft.EntityFrameworkCore;
namespace EmployeeApi.Data
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) {}
public DbSet<Employee> Employees { get; set; }
}
}
Register the DbContext in Program.cs:
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
Add connection string in appsettings.json:
"ConnectionStrings": {
"DefaultConnection": "Server=YOUR_SERVER_NAME;Database=EmployeeDb;Trusted_Connection=True;TrustServerCertificate=True;"
}
2.5 Implement EmployeesController
Controllers/EmployeesController.cs:
using EmployeeApi.Data;
using EmployeeApi.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
namespace EmployeeApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class EmployeesController : ControllerBase
{
private readonly AppDbContext _context;
public EmployeesController(AppDbContext context)
{
_context = context;
}
// GET: api/employees
[HttpGet]
public async Task<IActionResult> Get(
int page = 1,
int pageSize = 5,
string sortColumn = "Name",
string sortDirection = "asc",
string search = "")
{
var query = _context.Employees.AsQueryable();
// Filtering
if (!string.IsNullOrEmpty(search))
{
query = query.Where(e => e.Name.Contains(search) || e.Email.Contains(search) || e.Department.Contains(search));
}
// Sorting
query = sortDirection.ToLower() == "asc" ? query.OrderByDynamic(sortColumn, true) : query.OrderByDynamic(sortColumn, false);
var total = await query.CountAsync();
var data = await query.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();
return Ok(new { total, data });
}
// POST
[HttpPost]
public async Task<IActionResult> Post(Employee emp)
{
_context.Employees.Add(emp);
await _context.SaveChangesAsync();
return Ok(emp);
}
// PUT
[HttpPut("{id}")]
public async Task<IActionResult> Put(int id, Employee emp)
{
var dbEmp = await _context.Employees.FindAsync(id);
if (dbEmp == null) return NotFound();
dbEmp.Name = emp.Name;
dbEmp.Email = emp.Email;
dbEmp.Department = emp.Department;
await _context.SaveChangesAsync();
return Ok(dbEmp);
}
// DELETE
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
var emp = await _context.Employees.FindAsync(id);
if (emp == null) return NotFound();
_context.Employees.Remove(emp);
await _context.SaveChangesAsync();
return Ok();
}
}
public static class IQueryableExtensions
{
public static IQueryable<T> OrderByDynamic<T>(this IQueryable<T> source, string column, bool ascending)
{
if (string.IsNullOrEmpty(column)) return source;
var parameter = Expression.Parameter(typeof(T), "p");
var property = Expression.Property(parameter, column);
var lambda = Expression.Lambda(property, parameter);
string methodName = ascending ? "OrderBy" : "OrderByDescending";
var result = typeof(Queryable).GetMethods()
.Single(method => method.Name == methodName && method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), property.Type)
.Invoke(null, new object[] { source, lambda });
return (IQueryable<T>)result;
}
}
}

Join the conversation! Your thoughts help the community grow.