所以,我有一个相当大的关系数据库,我正在用C#/ .Net中的EntityFramework驱动。我正在尝试对其进行优化,以便更好地获取所选数据。
在尝试限制任何数据之前,我使用.AsNoTracking()
作为bool
输入到存储库。
到目前为止,我一直在使用存储库,其中所有相关表都包含在查询中,即使我只想搜索某些内容。
在返回.Include(...)
之前,我基本上得到了一个大量的IQueryable<Product>
列表。
但是说我只想返回几个特定的表(因为那些是我需要显示某些数据的唯一表),这样做的最佳方式是什么?
到目前为止,我的存储库中包含了该实体可用关系的枚举值列表。
我已经在这个列表中实现了循环,并尝试在每个必需的关系上执行.Include(...)
,但这似乎比加载所有内容要长得多(有时甚至超时并给我一个SQL超时) 。下面是一小部分内容。
query
是IQueryable<Product>
foreach (var part in this.IncludeList)
{
switch(part)
{
case ProductPart.Tag:
query = query.Include(p => p.Tags);
break;
case ProductPart.Video:
query = query.Include(p => p.Videos);
break;
}
}
我是否缺少使用这种脱链的诀窍?
答案 0 :(得分:-1)
请记住LINQ使用延迟执行计划。使用你的循环,你期望EF创建独立的查询并加载标签,然后加载视频。这不会发生什么。生成的查询将等同于:
query = query.Include(p => p.Tags).Include(p => p.Videos);
这可能会导致相当大的SQL事务。
如果要优化查询,请尝试以下操作:
foreach (var part in this.IncludeList)
{
switch(part)
{
case ProductPart.Tag:
query.SelectMany(p => p.Tags).Load();
break;
case ProductPart.Video:
query.SelectMany(p => p.Videos).Load();
break;
}
}
结果将更有效,因为每个查询将独立执行,导航属性将按实体框架映射到客户端。