Reputation: 52488
My environment: Windows 11 x64, .NET 7.0.2 , ASP.NET Core WebAPI 7.0.2 , Visual Studio 2022 Community edition, Microsoft SQL Server 2014 Express edition.
I install NuGet package, in csproj has
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="7.0.2" />
My try
public virtual DbSet<VoucherTypeCategory> VoucherTypeCategories { get; set; }
public virtual DbSet<VoucherTypeCategoryRefType> VoucherTypeCategoryRefTypes { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer("Server=.\\***********;Database=***********SampleVy;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=true");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new RoleConfiguration());
//modelBuilder.ApplyConfiguration(new CountryConfiguration());
//modelBuilder.ApplyConfiguration(new HotelConfiguration());
modelBuilder.Entity<Account>(entity =>
{
entity.HasKey(e => new { e.AccountId, e.AccountNumber });
(Please focus at these text ...Navigations": [] https://gist.github.com/donhuvy/1cc7f3d8a854ca803c5195ba6b3a93b8 )
As you seen, I have
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer("Server=.\\***********;Database=***********SampleVy;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=true");
but lazy loading still not work, Please guide me make lazy load work. How to enable lazy loading in Entity Framework Core 7.0.2 (.NET 7.0.2)?
Update 1: Maybe I used incorrect words, my ultimate purpose is don't loading so much data (1.95 MB JSON), I need data in one table only (few KB JSON).
Update 2: Use .AsNoTracking()
using acc.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Data;
namespace acc.Controllers
{
// Chart of accounts.
[Route("api/[controller]")]
[ApiController]
public class AccountTreeController : ControllerBase
{
private readonly ILogger<AccountTreeController> _logger;
private readonly Acc200Context _db;
public AccountTreeController(ILogger<AccountTreeController> logger, Acc200Context acc200Context)
{
_logger = logger;
_db = acc200Context;
}
// Get list of accounts of an tenant. For account tree.
[HttpGet("{tenant_id}/all/")]
[Authorize(Roles = "User")]
// [Authorize]
public IEnumerable<Account> Get(Guid tenant_id)
{
// return _db.Accounts.Where(x => x.TenantId == tenant_id).ToArray();
return _db.Accounts
.AsNoTracking()
.ToList();
}
Error (message in Postman)
{
"ErrorType": "Failure",
"ErrorMessage": "An error was generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning': An attempt was made to lazy-load navigation 'AccountDefaults' on a detached entity of type 'AccountProxy'. Lazy loading is not supported for detached entities or entities that are loaded with 'AsNoTracking'. This exception can be suppressed or logged by passing event ID 'CoreEventId.DetachedLazyLoadingWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'."
}
Update 3 Add .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
builder.Services.AddDbContext<Acc200Context>(options => options.UseSqlServer("Server=.\\************;Database=************;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=true")
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
);
Postman message
{
"ErrorType": "Failure",
"ErrorMessage": "An error was generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning': An attempt was made to lazy-load navigation 'AccountDefaults' on a detached entity of type 'AccountProxy'. Lazy loading is not supported for detached entities or entities that are loaded with 'AsNoTracking'. This exception can be suppressed or logged by passing event ID 'CoreEventId.DetachedLazyLoadingWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'."
}
Upvotes: 2
Views: 2352
Reputation: 550
The concept of lazy loading implies that the entity (or other data) is loaded when it is actually referenced/used. So, if you were running through a loop within an app and only referenced the parent entity, the child entity would not get loaded. However, if you refence and use the child entity, at that point it would get loaded.
If you expose an entity with sub entities through an API, the Web API/MVC serializer automatically references/uses all fields within the entity including the child entity during serialization of the response model as part result conversion. In this case, it would return all data including the child fields which are lazy loaded based on your setup.
If you really want to return part of the data, you have multiple options including:
Upvotes: 1