ORM for C# (.NET): Comparison of Entity Framework Core, Dapper, and NHibernate
When developing applications in C# (.NET), choosing the right ORM (Object-Relational Mapping) can significantly impact performance, development speed, and code maintainability. In this article, we will compare in detail the three most popular ORMs for the .NET ecosystem: Entity Framework Core (EF Core), Dapper, and NHibernate. You will learn their strengths and weaknesses, and also see specific code examples.
What is an ORM and why is it needed?
ORM is a technology that allows you to work with databases through programming language objects, rather than through direct SQL queries. For C# (.NET), ORM automates mapping tables to classes, SQL generation, change tracking, and transaction management. This speeds up development, but can lead to performance loss if used incorrectly.
1. Entity Framework Core (EF Core)
EF Core is a modern, lightweight, and extensible version of Entity Framework from Microsoft. It is a full-fledged ORM with a powerful LINQ provider, automatic migrations, and support for many DBMS (SQL Server, PostgreSQL, SQLite, MySQL, etc.).
Advantages:
- High development speed thanks to Code-First and Database-First approaches.
- Powerful LINQ syntax for writing queries.
- Automatic change tracking (Change Tracker).
- Built-in migration support.
Disadvantages:
- Slower compared to micro-ORMs (due to overhead from tracking).
- Difficulties with optimizing complex queries (N+1 problem).
Code example (EF Core):
// Modelpublic class User{ public int Id { get; set; } public string Name { get; set; } public string Email { get; set; }}
// Database contextpublic class AppDbContext : DbContext{ public DbSet<User> Users { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Server=(localdb)\\mssqllocaldb;Database=MyDb;"); }}
// Usageusing (var db = new AppDbContext()){ // Adding db.Users.Add(new User { Name = "Ivan", Email = "ivan@example.com" }); db.SaveChanges(); // Query via LINQ var users = db.Users.Where(u => u.Name.StartsWith("I")).ToList(); // Output foreach (var user in users) { Console.WriteLine($"{user.Id}: {user.Name}"); }}2. Dapper
Dapper is a micro-ORM created by the Stack Overflow team. It adds virtually no overhead and works directly with ADO.NET. Dapper is ideal for projects where performance and full control over SQL are critical.
Advantages:
- Maximum performance (close to "bare" ADO.NET queries).
- Simplicity and minimalism (one file, a few extension methods).
- Full control over SQL queries.
- Easily integrates into existing projects.
Disadvantages:
- No change tracking (everything is manual).
- No automatic migrations.
- Requires writing SQL queries manually.
Code example (Dapper):
public class User{ public int Id { get; set; } public string Name { get; set; } public string Email { get; set; }}
// Using Dapperusing (var connection = new SqlConnection(@"Server=(localdb)\\mssqllocaldb;Database=MyDb;")){ connection.Open(); // Insert var sqlInsert = "INSERT INTO Users (Name, Email) VALUES (@Name, @Email)"; connection.Execute(sqlInsert, new { Name = "Petr", Email = "petr@example.com" }); // Query