在构造函数中进行投影时无法访问导航属性

时间:2019-04-25 22:27:10

标签: c# entity-framework-core lazy-loading ef-core-2.2

我正在尝试将数据库实体从DbSet转换为上下文模型。我的数据库当前使用延迟加载来加载导航属性。我可以通过执行.Where(d => new ContextClass { Prop1 = d.Prop1, Prop2 = d.Prop2.Prop })来实现这一目标。但是,现在说ContextClass有一个接受d的构造函数,然后在其中进行属性初始化,就无法再访问导航属性并出现延迟加载问题。

我的对象

public class Entity1
{
  public string Prop1 { get; set; }
  public virtual Entity2 Prop2 { get; set; }
}

public class Entity2
{
  public string Prop { get; set; }
}

public class ContextClass
{
  public string Prop1 { get; set; }
  public string Prop2 { get; set; }

  public ContextClass()
  {
  }

  public ContextClass(Entity1 entity)
  {
    Prop1 = entity.Prop1;
    Prop2 = entity.Prop2.Prop;
  }
}

工作查询:

  .Select(e => new ContextClass
  {
    Prop1 = e.Prop1,
    Prop2 = e.Prop2.Prop
  })
  .ToListAsync();

非工作查询:

  .Select(e => new ContextClass(e))
  .ToListAsync();

这是我得到的错误:

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

1 个答案:

答案 0 :(得分:0)

我能够通过使用扩展方法执行通常的LINQ to SQL select语句而不是构造函数初始化来解决此问题。

public static IQueryable<ContextClass> SelectAsContext(this IQueryable<Entity1> queryable)
{
  return queryable.Select(x => new ContextClass
  {
    Prop1 = x.Prop1,
    Prop2 = x.Prop2.Prop
  });
}

因此在调用代码中:

var contexts = await queryable.SelectAsContext().ToListAsync();

构造函数的想法是这样,所以我不必每次都需要上下文时就强制转换它。使用这种扩展方法也可以达到相同的目的,因为逻辑仍然被封装。