Eager Loading In ASP.NET Core Web API Complete Example

In ASP.NET Core, eager loading is a technique used to load related data along with the main entity in a single database query. This helps to optimize performance by reducing the number of database calls. Let's implement an example of eager loading in an ASP.NET Core Web API using Entity Framework Core.

Create a new ASP.NET Core Web API Project

dotnet new webapi -n EagerLoadingInAsp.netCoreWebAPI
cd EagerLoadingInAsp.netCoreWebAPI

Install SQLite NuGet Package

Install the SQLite NuGet package to enable SQLite support in your project.

dotnet add package Microsoft.EntityFrameworkCore.Sqlite

Create a Model for your API

namespace EagerLoadingInAsp.netCoreWebAPI.Model
{
    public class Author
    {
        public int AuthorId { get; set; }
        public string Name { get; set; }
        public ICollection<Book> Books { get; set; }
    }
}

Create Model For Books

namespace EagerLoadingInAsp.netCoreWebAPI.Model
{
    public class Book
    {
        public int BookId { get; set; }
        public string Title { get; set; }
        public int AuthorId { get; set; }
        public Author Author { get; set; }
    }
}

Create the Application Database Context

using EagerLoadingInAsp.netCoreWebAPI.Model;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;

namespace EagerLoadingInAsp.netCoreWebAPI.ApplicationDbContext
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

        public DbSet<Author> Authors { get; set; }
        public DbSet<Book> Books { get; set; }
    }
}

Add the Dependencies in the Program.cs Class

using EagerLoadingInAsp.netCoreWebAPI.ApplicationDbContext;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;

// Add services to the container.
builder.Services.AddDbContext<AppDbContext>(options =>
        options.UseSqlite(configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if(app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Run the Migration

Run the Migration using the Application Manager Console

dotnet ef migrations add InitialCreate
dotnet ef database update

Check the SQL Lite Database For Tables

SQL Lite database

Create a Controller For Handling HTTP Requests

using EagerLoadingInAsp.netCoreWebAPI.ApplicationDbContext;
using EagerLoadingInAsp.netCoreWebAPI.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace EagerLoadingInAsp.netCoreWebAPI.Controllers
{
    [ApiController]
    [Route("api/[controller]/[Action]")]
    public class AuthorController: ControllerBase
    {
        private readonly AppDbContext _context;

        public AuthorController(AppDbContext context)
        {
            _context = context;
        }

        // GET: api/authors
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Author>>> GetAuthors()
        {
            // Eager loading using Include method
            var authors = await _context.Authors.Include(a => a.Books).ToListAsync();

            return authors;
        }

        // GET: api/authors/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Author>> GetAuthor(int id)
        {
            // Eager loading for a specific author by ID
            var author = await _context.Authors.Include(a => a.Books).FirstOrDefaultAsync(a => a.AuthorId == id);

            if(author == null)
            {
                return NotFound();
            }

            return author;
        }

        // POST: api/authors
        [HttpPost]
        public async Task<ActionResult<Author>> CreateAuthor(Author author)
        {
            _context.Authors.Add(author);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetAuthor", new { id = author.AuthorId }, author);
        }

        // PUT: api/authors/5
        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateAuthor(int id, Author author)
        {
            if(id != author.AuthorId)
            {
                return BadRequest();
            }

            _context.Entry(author).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch(DbUpdateConcurrencyException)
            {
                if(!_context.Authors.Any(a => a.AuthorId == id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        // DELETE: api/authors/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteAuthor(int id)
        {
            var author = await _context.Authors.FindAsync(id);
            if(author == null)
            {
                return NotFound();
            }

            _context.Authors.Remove(author);
            await _context.SaveChangesAsync();

            return NoContent();
        }
    }
}

The provided ASP.NET Core Web API AuthorController includes actions for performing CRUD operations on the Author the entity, with eager loading of related Book entities. It supports retrieving a list of authors, fetching a specific author by ID, creating a new author, updating an existing author, and deleting an author. The code emphasizes proper error handling and status code responses. Please customize it based on your application's requirements, database context, and entity models.

Output

Output

GitHub Project Url: https://github.com/SardarMudassarAliKhan/EagerLoadingInAsp.netCoreWebAPI

Conclusion

In conclusion, the provided code for the AuthorController in an ASP.NET Core Web API demonstrates a basic implementation for performing CRUD (Create, Read, Update, Delete) operations on the Author the entity, including the eager loading of related Book entities using Entity Framework Core.

Key points in the code included

  1. Eager loading of related Books using the Include method in the GetAuthors and GetAuthor actions.
  2. Actions to retrieve a list of authors (GetAuthors) and a specific author by ID (GetAuthor).
  3. Actions to create (CreateAuthor), update (UpdateAuthor), and delete (DeleteAuthor) authors.
  4. Proper error handling and status code responses, such as returning a 404 Not Found when an author is not present.

Please adapt the code based on your specific requirements, database context, and entity models. Additionally, consider adding input validation, error handling, and authentication/authorization mechanisms based on your application's needs.

If you want to study how to work with SQLite Database then read my complete article: https://www.c-sharpcorner.com/article/working-with-sql-lite-database-in-asp-net-core-web-api/