Dark theme quick reference for ORM concepts and a practical EF Core CRUD example.
ORM lets you interact with database tables using C# objects instead of writing raw SQL.
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
Server=ELIZA\SQLEXPRESS;Database=HealthcareSystem;Trusted_Connection=True;TrustServerCertificate=True;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace HandsOnEntityFrameworkCore.Entities
{
public class Doctor
{
[Key] // Primary key
public int DoctorId { get; set; }
[Required]
[MaxLength(100)] // NVARCHAR(100)
public string Name { get; set; } = string.Empty;
[Required]
[MaxLength(100)]
public string Specialization { get; set; } = string.Empty;
[StringLength(150)] // Optional with max length
public string? Qualification { get; set; }
[StringLength(50)]
public string? LicenseNumber { get; set; }
[Range(0, 60)] // 0..60 years experience
public int ExperienceYears { get; set; }
[Phone]
[StringLength(20)]
public string? PhoneNumber { get; set; }
[Column(TypeName = "time")] // map to SQL Server 'time'
public TimeSpan AvailabilityStart { get; set; }
[Column(TypeName = "time")]
public TimeSpan AvailabilityEnd { get; set; }
}
}
Use Fluent API in OnModelCreating for relationships, indexes, and advanced configuration.
Note: Namespace uses the same spelling you provided (DbContextFloder).
using HandsOnEntityFrameworkCore.Entities;
using Microsoft.EntityFrameworkCore;
namespace HandsOnEntityFrameworkCore.DbContextFloder
{
internal class AppDbContext : DbContext
{
public DbSet<Doctor> Doctors { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=ELIZA\\SQLEXPRESS;Database=HealthcareSystem;Trusted_Connection=True;TrustServerCertificate=True;");
}
}
}
using HandsOnEntityFrameworkCore.DbContextFloder;
using HandsOnEntityFrameworkCore.Entities;
using System;
using System.Linq;
namespace HandsOnEntityFrameworkCore
{
internal class Program
{
static void Main(string[] args)
{
using var context = new AppDbContext();
// Ensure database and table are created (simple dev approach)
context.Database.EnsureCreated();
// Insert
var doctor2 = new Doctor
{
Name = "Dr. Asha Mehta",
Specialization = "Dermatologist",
LicenseNumber = "LIC2222",
Qualification = "MBBS, DDVL",
ExperienceYears = 7,
PhoneNumber = "9123456789",
AvailabilityStart = new TimeSpan(10, 0, 0),
AvailabilityEnd = new TimeSpan(14, 0, 0)
};
context.Doctors.Add(doctor2);
context.SaveChanges();
Console.WriteLine("✅ Doctor inserted.");
// Read
var doctors = context.Doctors.ToList();
Console.WriteLine("\n👨⚕️ All Doctors:");
foreach (var doc in doctors)
{
Console.WriteLine($"{doc.DoctorId}: {doc.Name} - {doc.Specialization}");
}
// Update
var firstDoctor = context.Doctors.FirstOrDefault();
if (firstDoctor != null)
{
firstDoctor.Specialization = "Senior Cardiologist";
context.SaveChanges();
Console.WriteLine("✏️ Doctor updated.");
}
// Delete
if (firstDoctor != null)
{
context.Doctors.Remove(firstDoctor);
context.SaveChanges();
Console.WriteLine("❌ Doctor deleted.");
}
}
}
}
Alternative: replace EnsureCreated() with migrations (recommended for real apps).
dotnet ef migrations add InitialCreate
dotnet ef database update
Tip: For migrations commands, ensure the Microsoft.EntityFrameworkCore.Tools package is installed and the project builds.