Getting “attempt was made to lazy-load navigation property on detached entity” despite eager fetch

不羁的心 提交于 2019-11-30 20:26:25

For posterity, here's the response from the EF Core team:

This is because lazy-loading isn't supported for NoTracking queries (#10042) but we tried to not make it throw if it looked like lazy-loading wasn't needed. In retrospect it might have been better to always throw. Note that the warning can be configured to not throw using ConfigureWarnings in the DbContextOptionsBuilder.

Just in case it's of use for someone, what I ended up doing was creating a second "ReadOnlyRepository" configured to not use lazy loading and to always return untracked sets. I use this repository for queries where I'm never going to persist changes to any of the entities, where the resultset can be large and when it needs to perform well.

public class ReadOnlyRepository : MainDbContextBase, IReadOnlyRepository
{
    public ReadOnlyRepository(IConfigurationSettings configurationSettings)
        : base(configurationSettings, false)
    {
    }

    public IQueryable<T> Retrieve<T>() where T : class, IAmAnAggregateRoot
    {
        return GetDbSet<T>().AsNoTracking();
    }
}

public class MainDbContextBase : DbContext
{
    private readonly IConfigurationSettings configurationSettings;
    private readonly bool useLazyLoading;

    protected MainDbContextBase(IConfigurationSettings configurationSettings, bool useLazyLoading)
    {
        this.configurationSettings = configurationSettings;
        this.useLazyLoading = useLazyLoading;
    }

    protected DbSet<T> GetDbSet<T>() where T : class
    {
        return Set<T>();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder
                .UseLazyLoadingProxies(useLazyLoading)
                .UseSqlServer(configurationSettings.ConnectionString);
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        ...
    }
}

}

There's no bug. Since you are not tracking changes using .AsNoTracking, lazy loading will never work. You can use .Include("ChildEntity") in your query or give up of using .AsNoTracking.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!