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 theUPDATEitself. - follows relationships. A
Categoryobject can have aProductslist, 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