ASP.NET Core 7 Web API. Lazy loading is a technique where related data is only loaded from the database when it is explicitly requested. In Entity Framework Core, lazy loading can be achieved by marking navigation properties as virtual.
Create a new ASP.NET Core Web API Project
dotnet new webapi -n LazyLoadingInAspNetCoreWebApI
cd LazyLoadingInAspNetCoreWebApI
Install SQLite NuGet Package
Install the SQLite NuGet package to enable SQLite support in your project.
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
Let's assume you have two entities, Author
and Book
, where an author can have multiple books. Here's a simple example:
Create your model classes
In the Author
and Book
classes, the navigation property Books
is marked as virtual
. This is a key step in enabling lazy loading for these navigation properties.
namespace LazyLoadingInAspNetCoreWebApI.Models
{
public class Author
{
public int AuthorId { get; set; }
public string Name { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
}
The use of the virtual
keyword allows Entity Framework Core to generate proxies for these classes, which can then intercept calls to navigation properties and load the related data on demand.
Create Books Model
namespace LazyLoadingInAspNetCoreWebApI.Models
{
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public int AuthorId { get; set; }
public virtual Author Author { get; set; }
}
}
Create the Application Database Context
using LazyLoadingInAspNetCoreWebApI.Models;
using Microsoft.EntityFrameworkCore;
namespace LazyLoadingInAspNetCoreWebApI.AppDbContext
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
}
}
Add the Dependencies in the Program.cs Class
Make sure you have the necessary NuGet packages installed, including Microsoft.EntityFrameworkCore.Sqlite
and Microsoft.EntityFrameworkCore.Proxies
. Also, ensure that your DefaultConnection
in the configuration is properly set up with the correct SQLite connection details.
using LazyLoadingInAspNetCoreWebApI.AppDbContext;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using System;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var configuration = builder.Configuration;
// Add services to the container.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseLazyLoadingProxies().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(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Lazy Loading In Asp.net Core Web API", Version = "v1" });
});
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();
Add the Database Connection
// appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=LazyLoading.db"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Run the Migration
dotnet ef migrations add InitialCreate
dotnet ef database update
Check the SQL Lite Database For Tables
Create a Controller For Handling HTTP Requests
using LazyLoadingInAspNetCoreWebApI.AppDbContext;
using LazyLoadingInAspNetCoreWebApI.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace LazyLoadingInAspNetCoreWebApI.Controllers
{
[Route("api/[controller]/[Action]")]
[ApiController]
public class AuthorsController : ControllerBase
{
private readonly ApplicationDbContext _context;
public AuthorsController(ApplicationDbContext context)
{
_context = context;
}
// GET: api/authors
[HttpGet("GetAllAuthor")]
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("{GetAuthorById}")]
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("CreateAuthor")]
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("UpdateAuthorById")]
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("DeleteAuthorById")]
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();
}
}
}
Output
GitHub Project URL: https://github.com/SardarMudassarAliKhan/LazyLoadingInAspNetCoreWebApI
Conclusion
In conclusion, the provided code configures and registers an Entity Framework Core DbContext for an ASP.NET Core application. It uses SQLite as the database provider and enables lazy loading through the Entity Framework Core Proxies library.
Here's a summary of the key points.
-
The AddDbContext<ApplicationDbContext>
the method registers the application DbContext
(assumed to be ApplicationDbContext
) with the dependency injection container.
-
The UseLazyLoadingProxies()
method enables proxy-based lazy loading, allowing related data to be loaded from the database only when accessed.
-
UseSqlite(configuration.GetConnectionString("DefaultConnection"))
configures the DbContext to use SQLite as the database provider and retrieves the connection string from the application's configuration.
Ensure that you have the necessary NuGet packages installed, including Microsoft.EntityFrameworkCore.Sqlite
and Microsoft.EntityFrameworkCore.Proxies
. Additionally, make sure your SQLite connection string in the configuration is correctly set up with the appropriate details for your SQLite database.
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/