0

I have the following model:

public partial class Device
{
    public int Id { get; set; }
    public virtual Tablet Tablet { get; set; }

where Tablet is the following:

public class Tablet
{
    public string TabletId { get; set; }

    public int DeviceId { get; set; }
    public virtual Device Device { get; set; }

    private ICollection<TabletTransferRequest> _tabletTransferRequests;
    public virtual ICollection<TabletTransferRequest> TabletTransferRequests { get => _tabletTransferRequests ?? (_tabletTransferRequests = new List<TabletTransferRequest>()); protected set => _tabletTransferRequests = value; }
}

and the mapping class:

public class TabletMap : IEntityTypeConfiguration<Tablet>
{
    public void Configure(EntityTypeBuilder<Tablet> builder)
    {
        builder.ToTable(nameof(Tablet));
        builder.HasKey(p => p.TabletId);

        builder.HasOne(p => p.Device)
            .WithOne(o => o.Tablet)
            .HasForeignKey<Tablet>(p => p.DeviceId)
            .IsRequired()
            .OnDelete(DeleteBehavior.Restrict)
            ;
    }
}

DTO classes:

public class DeviceDisplayDto
{
    public int Id { get; set; }
    public TabletPartDto Tablet { get; set; }
}

public class TabletPartDto
{
    public string TabletId { get; set; }
    public List<TabletTransferRequestElementDto> TabletTransferRequests { get; set; }
}


public class TabletTransferRequestElementDto : DeviceRequestElementAbstractDto
{
    public string TabletId { get; set; }
    public int DeviceId { get; set; }
}

when I try to do the following

        var query = _context.Devices.Include(d => d.Tablet).ThenInclude(d => d.TabletTransferRequests);
        var devices = new PagedList<DeviceDisplayDto>(query.ProjectTo<DeviceDisplayDto>(_mapperConfig), pageIndex, pageSize);

I got the following:

Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning: An attempt was made to lazy-load navigation property 'TabletTransferRequests' on detached entity of type 'TabletProxy'. 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'.

why it's detached?

Oleg Sh
  • 8,496
  • 17
  • 89
  • 159
  • To my knowledge, this happens when you use AsNoTracking() in your query, but your posted code doesn't show that. https://forums.asp.net/t/2167300.aspx?Problem+to+use+AsNoTracking+query+in+master+detail+entities+ – insane_developer Dec 20 '20 at 15:23
  • Does this help? https://stackoverflow.com/questions/20757594/ef-codefirst-should-i-initialize-navigation-properties QUOTE: "In EF-core 3, initializing a reference navigation property prevents Include from working properly." – Neil W Dec 20 '20 at 15:31
  • Also potentially relevant to your motivation to instantiate in get ... Null coalesce assignment is also handy for dealing with potentially empty collections: (col ??= new col()).Add() will allow you to instantiate null collection and add in one line. If col not null, then use it, else instantiate it and use it. – Neil W Dec 20 '20 at 15:35
  • This should not happen when projecting to dtos. (and `Include` / `ThenInclude` are not needed). With that in mind, which line generates the exception (can we see the exception stack trace)? Also can we see the missing classes (`TabletTransferRequest`, `DeviceRequestElementAbstractDto`) and AutoMapper mappings? – Ivan Stoev Dec 20 '20 at 17:01

1 Answers1

0

Is the error occurring on the var devices = new PagedList(...) or later, such as when the controller method completes? I don't recognize that PagedList implementation, but from what you've typed that rendition appears to be initializing with IQueryable<T> rather than a static collection IList<T> which may be an issue if the PagedList ends up attempting to resolve paging from the IQueryable after an initial load.

Normally PagedList would utilize a ToPagedList(page, pageSize) method when working with IQueryable which would trigger a one-off load of a Page. If written as a class initialized with an IQueryable, a data retrieval query could be non-fillable if queried after the DbContext is disposed.

Steve Py
  • 26,149
  • 3
  • 25
  • 43