Tutorials Entity Framework Core Tutorial
Repository Layer Design with EF Core
Repository Layer Design with EF Core: free step-by-step lesson with examples, common mistakes, and interview tips — part of Entity Framework Core Tutorial on Toolliyo Academy.
On this page
Entity Framework Core Tutorial · Lesson 74 of 100
Repository Layer Design with EF Core
Beginner ✓ → Intermediate ✓ → Advanced ✓ → Professional
Professional · 4 — Real projects · ~10 min · Module 8: Enterprise Architecture
What is this?
Repository layer design defines focused interfaces per aggregate — IOrderRepository, IProductRepository — implementing EF queries behind Application contracts.
Why should you care?
ShopNest Application layer should not know about Include chains — repository methods express domain language like GetOpenOrdersForCustomer.
See it live — copy this example
Paste into a .NET project with EF Core packages, then run with LocalDB/SQL Server (dotnet ef / dotnet run).
public interface IOrderRepository
{
Task<Order?> GetWithItemsAsync(int orderId, CancellationToken ct);
Task<IReadOnlyList<Order>> ListRecentForCustomerAsync(int customerId, int take, CancellationToken ct);
}
public class OrderRepository(ShopNestDbContext db) : IOrderRepository
{
public Task<Order?> GetWithItemsAsync(int orderId, CancellationToken ct) =>
db.Orders.Include(o => o.Items).FirstOrDefaultAsync(o => o.Id == orderId, ct);
public async Task<IReadOnlyList<Order>> ListRecentForCustomerAsync(int customerId, int take, CancellationToken ct) =>
await db.Orders.AsNoTracking()
.Where(o => o.CustomerId == customerId)
.OrderByDescending(o => o.OrderDate)
.Take(take)
.ToListAsync(ct);
}
What happened?
- Repository methods encapsulate EF specifics.
- Application calls GetWithItemsAsync instead of composing Include itself.
Practice next
- Name methods after domain operations not generic GetAll.
- Keep interfaces in Application; implementations in Infrastructure.
- Return domain entities or dedicated read DTOs — not IQueryable.
- Split read methods into IOrderReadRepository using projections only.
- Add specification pattern for reusable filter objects internally.
Remember
Repositories express domain data operations. Hide Include and filter details inside. Interfaces live in Application layer.
ShopNest order repository
Support portal uses ListRecentForCustomerAsync without copying Include logic in three services.
Outcome: Query changes happen once in OrderRepository.
Interview prep for this lesson
Practice these questions aloud after reading—each links to a full structured answer.
Sign in to ask a question or upvote helpful answers.
No questions yet — be the first to ask!