我急切地加载(通过使用 .Include())相关实体,以尽量减少为特别“大量”数据网格生成的 SQL 查询的数量。在 POCO 中,相关实体是公共虚拟导航属性,这意味着它们是延迟加载的。我想保留延迟加载这些相关实体的默认行为,因为它最适合我项目的其他部分。
现在,在预先加载相关实体之后,我可以看到仍然有相当数量的查询生成。这是仅针对为空的相关实体的查询(空只是因为 sql 连接“发现”没有相关数据)。
这让我相信,当我稍后在表示层访问它们时,EF 会尝试延迟加载这些实体(认为它们尚未加载)。
我是否错过了一些基本的东西,或者有什么办法可以解决这个问题?
示例代码
使用存储库模式,这里有一些简化的方法(省略分页、排序、过滤等)。
通用存储库中的获取方法
public IEnumerable<T> Get(
Expression<Func<T, object>>[] includes = null)
{
IQueryable<T> query = set;
...
// Include properies for eager loading
if (includes != null)
{
query = includes.Aggregate(query,
(current, include) => current.Include(include));
}
...
return query.ToList();
}
上面是从服务类调用的,像这样
...
context.Licenses.Get(
includes: new Expression<Func<License, object>>[] { l => l.Comment }
);
...
许可 POCO
public class License
{
public License()
{
}
// Primitive properties
public string ID { get; set; }
public string Name { get; set; }
...
// Navigation properties
public virtual LicenseComment Comment { get; set; }
...
}
许可证评论 POCO
public class LicenseComment
{
public LicenseComment()
{
}
// Primitive properties
public string LicenseID { get; set; }
public string Comment { get; set; }
}
在 MVC Razor 视图(或为此而在模型中)访问属性
<span>@license.Comment</span>
每当我尝试访问一个为 null 的 License.Comment(通过 SQL Server Profiler 查找)时,都会生成额外的 SQL 查询,在我看来,实体框架延迟加载会启动,即使我急切地包含了这个属性。