【问题标题】:Create DbQuery From lazy loading models从延迟加载模型创建 DbQuery
【发布时间】:2019-12-16 12:17:00
【问题描述】:

是否可以从具有延迟加载导航属性的模型创建 DbQuery?当我尝试这样做时,出现以下错误

从“Castle.Proxies.ExtendedStudentProxy”上的“前缀”获取值 --> 无法跟踪“ExtendedStudent”类型的实例,因为它是查询类型,只能跟踪实体类型。

我认为 DbQuery 是只读的,所以不应该将它们作为默认行为进行跟踪吗?我错了吗?

这是我使用的代码示例:

型号:

public class ExtendedStudent {
    public string FirsName {get; set;}
    public virtual Prefix Prefix {get; set;}
}

public class Prefix {
    public int Id {get; set;}
    public string Name {get; set;}
}

Startup.cs

   builder.AddDbContext<ApplicationDbContext>( b => b.UseLazyLoadingProxies()
       .UseSqlServer(connectionString));

ApplicationDbContext.cs

public class ApplicationDbContext {

    ...
    public DbSet<Proxy> Proxies {get; set;}
    public DbQuery<ExtendedStudent> ExtendedStudents {get; set;}
    ...
}

【问题讨论】:

  • 正如您在下面看到的,关于这一点还有很多话要说。应该问的第一个问题是:你能显示引发异常的代码吗?查询类型不被跟踪(也不应该被跟踪),但您似乎以仅适用于实体类型的方式查询它们。

标签: c# entity-framework-core lazy-loading sql-view ef-core-2.1


【解决方案1】:

是的,他们没有被跟踪。这是默认的(也是唯一的)行为。我认为这个例外是一种有点笨拙的方式来说明这一点。非跟踪类型包含跟踪实体会很奇怪。另外,请注意,没有用于查询类型的映射 API 来定义关系,因此它显然不受支持。

不能做到这一点的主要原因是查询类型可以从任何类型的SQL中查询出来,不能保证查询类型后面的查询是可组合的。完全可以从存储过程中填充查询类型。那么 SQL 就没有办法,更不用说 EF 了,将结果与表连接起来以填充导航属性。

【讨论】:

  • 没有用于查询类型的映射 API 来定义关系部分并不完全正确。由于根据定义查询类型是无键,唯一的限制是它们不能位于关系的主体,如explained in the docs - 以开头的段落仅支持导航映射的子集能力。因此,在 OP 示例中,支持参考导航属性(和 FK)。只是被引用的实体不能有反向集合导航属性。
  • 顺便说一句,在大多数情况下查询类型的查询可组合的,支持Include等。仅供参考:)
  • 我的天啊,看来我应该深入研究一下才能知道我在说什么!
  • 大声笑,也许你不应该,至少现在。因为看起来 EF Core 的设计者并不清楚他们在做什么——客户端 eval、查询类型。在 3,0 中前者将被移除而Query types are consolidated with entity types,基本上引入了 keyless 实体类型概念。
  • 是的,我不是第一次对沉浸在 EF 核心的深度中感到谨慎。这不是我第一次尝试深入了解事情的真相,只是后来看到底部更改了 coupla 版本。
猜你喜欢
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 2018-05-22
  • 2014-01-15
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
相关资源
最近更新 更多