Skip to content

Projections : Entity Framework Core

Overview

Projections in Entity Framework Core are a way to select specific parts of your entity model rather than returning the full entity. This is useful for performance and separation of concerns — especially when you only need a subset of data (e.g. for a view model, DTO, or UI list).

What Are Projections in EF Core?

A projection transforms your query results into another shape using .Select(). You can:

  • Project into anonymous types
  • Project into DTOs / ViewModels
  • Use partial columns to reduce the size of your result set

It’s equivalent to writing a SELECT Name, Price FROM Products in SQL rather than SELECT *.

Advantages of Using Projections

  • Performance: Only retrieves the data you need (fewer columns, less memory).
  • Security: Avoid exposing unnecessary data (like passwords or foreign keys).
  • Clear intent: Makes the purpose of the query obvious.
  • Better for frontend APIs: Map data to shape expected by consumer.

Drawbacks

  • You lose change tracking if you project into anything other than an entity.
  • You can’t easily update the database from the projected object.
  • Some complex projections (especially involving navigation properties) can be tricky.

Example: Projection with Anonymous Type

Suppose you have the following model:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public Category Category { get; set; }
}

Projecting to an anonymous type

var products = await _context.Products
    .Select(p => new 
    {
        p.Name,
        p.Price,
        CategoryName = p.Category.Name
    })
    .ToListAsync();

This returns a list of anonymous objects like:

{ Name = "Apples", Price = 1.20m, CategoryName = "Fruit" }

Projecting to a DTO

public class ProductDto
{
    public string Name { get; set; }
    public string CategoryName { get; set; }
}

var products = await _context.Products
    .Select(p => new ProductDto
    {
        Name = p.Name,
        CategoryName = p.Category.Name
    })
    .ToListAsync();

Notes on Anonymous Type Usage

  • Great for read-only scenarios (like sending data to UI).
  • You can't return them from a method unless it's dynamic or part of the same LINQ query scope.
  • You can use them inside Razor views or inside controller methods if you don’t need to strongly type the result.

Pro Tips

  • Always project before calling .ToListAsync() to make sure only the needed fields are pulled from the DB.
  • You can project nested navigation properties — but EF Core must be able to translate the query to SQL.
  • For large results or API endpoints, consider using AsNoTracking() to disable change tracking for better performance.

Summary

Concept Description
Projection Selecting a subset of fields or mapping entities to a new shape
Anonymous Type Used in .Select() when you don’t need a named class
When to Use UI lists, DTOs, or when minimizing data transfer
Key Syntax .Select(x => new { x.Foo, x.Bar })