Linq2Sql:查询 - 子查询优化

时间:2011-01-15 04:25:26

标签: .net linq linq-to-sql optimization query-optimization

我有以下查询:

            IList<InfrStadium> stadiums =
                (from sector in DbContext.sectors
                 where sector.Type=typeValue
                 select new InfrStadium(sector.TeamId)
                ).ToList();

和InfrStadium类构造函数:

    private InfrStadium(int teamId)
    {
        IList<Sector> teamSectors = (from sector in DbContext.sectors
                                     where sector.TeamId==teamId
                                     select sector)
                                     .ToList<>();
        ... work with data
    }

当前实现执行1 + n个查询,其中n - 第一次获取的记录数。

我想优化它。

另一个我喜欢用'group'操作符这样做的方式:

            IList<InfrStadium> stadiums =
                (from sector in DbContext.sectors
                 group sector by sector.TeamId into team_sectors
                 select new InfrStadium(team_sectors.Key, team_sectors)
                ).ToList();

使用适当的构造函数:

    private InfrStadium(int iTeamId, IEnumerable<InfrStadiumSector> eSectors)
    {
        IList<Sector> teamSectors = eSectors.ToList();

        ... work with data
    }

但尝试启动查询会导致以下错误:

  

'System.Int32'类型的表达式   不能用于构造函数   类型的参数   'System.Collections.Generic.IEnumerable`1 [InfrStadiumSector]'

问题1:

请你解释一下,这里有什么问题,我不明白为什么'team_sectors'被应用为'System.Int32'?

我尝试稍微更改一下查询(用IQueryeable替换IEnumerable):

            IList<InfrStadium> stadiums =
                (from sector in DbContext.sectors
                 group sector by sector.TeamId into team_sectors
                 select new InfrStadium(team_sectors.Key, team_sectors.AsQueryable())
                ).ToList();

使用适当的构造函数:

    private InfrStadium(int iTeamId, IQueryeable<InfrStadiumSector> eSectors)
    {
        IList<Sector> teamSectors = eSectors.ToList();

        ... work with data
    }

在这种情况下,我收到了另一个但类似的错误:

  

'System.Int32'类型的表达式   不能用于类型的参数   “System.Collections.Generic.IEnumerable 1[InfrStadiumSector]' of method 'System.Linq.IQueryable 1 [InfrStadiumSector]   AsQueryableInfrStadiumSector'

问题2:

实际上,同样的问题:根本无法理解这里发生的事情......

P.S。 我有另一个优化查询的想法(在这里描述:Linq2Sql: query optimisation),但我很乐意找到一个解决方案,其中有一个请求DB。)

2 个答案:

答案 0 :(得分:3)

首先,在本地提取数据并将其放入满足您需求的结构中。

ILookup<int, InfrStadiumSector> sectorLookup =
(
  from sector in DbContext.sectors
  where sector.Type == typeValue
  select sector
).ToLookup(sector => sector.TeamId);

然后将该查找中的每个分组投影到InfrStadium的实例中(不返回数据库)......

IList<InfrStadium> stadiums = sectorLookup
  .Select(x => new InfrStadium(x.Key, x))
  .ToList();

该投影使用此构造函数。

private InfrStadium(int iTeamId, IEnumerable<InfrStadiumSector> eSectors)

答案 1 :(得分:1)

如果没有一点实验,我无法确定是怎么回事。您确定构造函数中参数的顺序吗?如果是这样,那么翻译表达式可能会出现问题。在尝试构造InfrStadium对象之前,您可能希望尝试实现查询。我将使用扩展方法重写,因为我认为它更容易阅读。

var stadiums = DbContext.sectors
                        .ToLookup( s => s.TeamId )
                        .Select( g => new InfrStadium( g.Key, g ) )
                        .ToList();