多次使用实体框架Include()...但是单独使用

时间:2014-10-29 10:53:39

标签: c# linq entity-framework optimization

所以,我有一个相当大的关系数据库,我正在用C#/ .Net中的EntityFramework驱动。我正在尝试对其进行优化,以便更好地获取所选数据。

在尝试限制任何数据之前,我使用.AsNoTracking()作为bool输入到存储库。

到目前为止,我一直在使用存储库,其中所有相关表都包含在查询中,即使我只想搜索某些内容。

在返回.Include(...)之前,我基本上得到了一个大量的IQueryable<Product>列表。

但是说我只想返回几个特定的​​表(因为那些是我需要显示某些数据的唯一表),这样做的最佳方式是什么?

到目前为止,我的存储库中包含了该实体可用关系的枚举值列表。

我已经在这个列表中实现了循环,并尝试在每个必需的关系上执行.Include(...),但这似乎比加载所有内容要长得多(有时甚至超时并给我一个SQL超时) 。下面是一小部分内容。

queryIQueryable<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;
    }
}

我是否缺少使用这种脱链的诀窍?

1 个答案:

答案 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;
    }
}

结果将更有效,因为每个查询将独立执行,导航属性将按实体框架映射到客户端。