我是一名有用的助手,可以为您翻译文本。
我有一个问题,我认为许多专业开发人员都会遇到。我工作的地方采用了实体框架。我们使用它,并且很喜欢它。然而,我们似乎遇到了一个非常令人沮丧的限制。
假设您有一个对象链如下:
A->B->C->D
我们是专业人士,所以这些对象拥有大量数据,它们在各自的数据库表中也有很多。看起来 EF 加载超过 B 对象的任何内容时都会出现问题。它生成的 SQL 查询非常低效且不好。调用可能是这样的:
我们通过使用 .Load() 命令明确加载第二级别之后的对象来解决了这个问题。对于单个对象,这种方法很有效。但是,当涉及到对象集合时,我们开始遇到 .Load() 的问题。
我有一个问题,我认为许多专业开发人员都会遇到。我工作的地方采用了实体框架。我们使用它,并且很喜欢它。然而,我们似乎遇到了一个非常令人沮丧的限制。
假设您有一个对象链如下:
A->B->C->D
我们是专业人士,所以这些对象拥有大量数据,它们在各自的数据库表中也有很多。看起来 EF 加载超过 B 对象的任何内容时都会出现问题。它生成的 SQL 查询非常低效且不好。调用可能是这样的:
context.objects.include("bObjectName.cObjectName.dObjectName").FirstOrDefault(x => x.PK == somePK);
我们通过使用 .Load() 命令明确加载第二级别之后的对象来解决了这个问题。对于单个对象,这种方法很有效。但是,当涉及到对象集合时,我们开始遇到 .Load() 的问题。
首先,似乎没有办法在不使用 virtual 关键字的情况下保持对象集合的代理跟踪。这很有道理,因为它需要重写 get 和 set 函数。然而,这样会启用延迟加载,而 .Load() 不会在启用延迟加载时映射实体。我自己觉得这有点奇怪。如果您删除 virtual 关键字,则 .Load() 会自动将加载的对象链接到上下文中相关的对象。
因此,这就是我的问题所在。我想要代理跟踪,但也希望 .Load() 为我映射导航属性。如果 EF 可以生成良好的查询,所有这些都不会成为问题。我了解为什么它无法生成良好的查询,因为它必须是一次适用于所有情况的展示。
因此,为了加载第三层对象,我可以在我的服务层中创建一个加载函数,该函数获取第二层对象的所有主键,然后调用其中的一个 .Load()。
任何人有解决方案吗?EF7 或 Core 1.0 似乎通过以下方式解决了这个问题:
- 完全删除延迟加载,我们也可以关闭它,但这会破坏很多旧代码。
- 添加了一个新的 "ThenInclude" 功能,据说大大提高链接包含的效率。
如果关闭延迟加载是答案,那没关系,我只是想在浪费大量时间重新开发大量服务调用的 Web 应用程序之前尽可能地用完所有选项。
任何人有任何想法吗?我们正在使用 EF6。
编辑:看起来关闭上下文级别的延迟加载或升级到 EF7 是答案。如果有人找到一种在 EF6 中可以强制启用代理跟踪的方法并进行强制及时加载单个对象的解决方案,我将更改此内容。
Load()
是一个渴望加载方法,它如何与懒惰加载相关呢?以及它如何映射*实体?实际上,我们需要的是代码。 - Gert Arnold