【问题标题】:Cannot access navigation properties when projecting within a constructor在构造函数中投影时无法访问导航属性
【发布时间】:2019-04-26 22:34:14
【问题描述】:

我正在尝试将我的数据库实体从 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'.

【问题讨论】:

  • 干脆不要使用这样的构造函数。正如您已经看到的,它们不起作用,我的意思是,不能翻译成 SQL 并在本地进行评估。使用工作示例中的属性投影。
  • @Renat 不是我想要的,因为我已经有了这些管道设置。
  • @IvanStoev 我想从设计的角度来看你是对的。它正在执行 LINQ to SQL,并且无法翻译此类构造函数。

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


【解决方案1】:

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

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();

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 2012-07-06
    • 2019-10-15
    • 2019-05-21
    • 2020-12-17
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多