What is an ORM?

An ORM (object-relational mapper) moves data between C# objects and database tables. Dapper is a micro-ORM, where you write the SQL and it fills the objects. Entity Framework Core is a full ORM, where you write LINQ and it writes the SQL, and also tracks and saves your changes.

Journeyman · C# · Entity Framework Core · Updated

After this lesson you can

  • Explain what an ORM does, and how Entity Framework Core differs from Dapper

Key takeaways

  • An ORM moves data between C# objects and database tables.
  • Dapper is a micro-ORM: you write the SQL, and it fills the objects.
  • EF Core is a full ORM: you write LINQ, and it writes the SQL, so the filtering and sorting still happen in the database.
  • EF Core also tracks and saves your changes and follows relationships, at the cost of some control, more to learn and a little speed.

Your C# code thinks in objects: a Category with a CategoryName property. SQL Server thinks in tables: a Categories row with a CategoryName column. Every app that uses a database has to move data back and forth between the two shapes.

You've done that three ways so far:

Way You write Who fills the objects
ADO.NET The SQL, plus a loop reading each column from a SqlDataReader You
Dapper The SQL Dapper, by matching column names to properties
Entity Framework Core No SQL: LINQ Entity Framework Core, which also writes the SQL

A library that maps between objects and tables is called an ORM, an object-relational mapper. Dapper is a small one, often called a micro-ORM. Entity Framework Core (EF Core) is Microsoft's full one.

The same query, two ORMs

The products under $10, with Dapper:

using SqlConnection connection = new SqlConnection(connectionString);
List<Product> cheap = (await connection.QueryAsync<Product>(
    "SELECT ProductId, ProductName, UnitPrice FROM Products WHERE UnitPrice < @MaxPrice ORDER BY ProductName;",
    new { MaxPrice = 10m })).ToList();

And with EF Core:

List<Product> cheap = await db.Products
    .Where(p => p.UnitPrice < 10m)
    .OrderBy(p => p.ProductName)
    .ToListAsync();

The EF Core version is LINQ, exactly as in LINQ and Lambdas, but db.Products isn't a list in memory: it stands for the Products table. EF Core translates the whole chain into one SQL query, sends it to SQL Server, and fills a Product for each row that comes back:

SELECT [p].[ProductId], [p].[CategoryId], [p].[Discontinued], [p].[ProductName], [p].[UnitPrice], [p].[UnitsInStock]
FROM [Products] AS [p]
WHERE [p].[UnitPrice] < 10.0
ORDER BY [p].[ProductName]

The filtering and sorting happen in the database, as they should, not in your program.

What a full ORM adds

Writing SQL for you is only the start. EF Core also:

  • tracks changes. Load a product, change its price, call SaveChanges(), and EF Core works out and runs the UPDATE itself.
  • follows relationships. A Category object can have a Products list, filled by a join EF Core writes.
  • can create and change the database from your classes, with migrations. (This course uses existing databases, so you won't need them yet.)

What it costs

  • Less control. The SQL is EF Core's, not yours. It's usually good, but when a query is slow, you have to read SQL you didn't write.
  • More to learn. Tracking, relationships, configuration: a full ORM has a lot of behavior to understand.
  • A little slower. All that work takes time, though for most apps the difference is small.

The last lesson in this topic compares the two properly. First, the next two lessons show EF Core at work.

Check yourself

1 question to try on the lesson page.

So what

An ORM moves data between objects and tables so you don't have to. Dapper does the moving and leaves the SQL to you; EF Core writes the SQL too, from the LINQ you already know.

Key terms

  • ORM
  • Micro-ORM
  • Entity Framework Core

Cheat sheets