Linq2Sql: запрос - оптимизация подзапроса - PullRequest
0 голосов
/ 15 января 2011

У меня следующий запрос:

            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'?

Я пытался немного изменить запрос (заменить IEnumerable на IQueryeable):

            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: оптимизация запроса ), но я бы хотел найти решение с 1 запросом к БД).

Ответы [ 2 ]

3 голосов
/ 15 января 2011

Сначала извлеките данные локально и поместите их в структуру, соответствующую вашим потребностям.

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 голос
/ 15 января 2011

Я не могу быть уверен, что происходит без небольших экспериментов.Вы уверены в порядке ваших параметров в конструкторе?Если так, то это может быть проблемой при переводе выражения.Возможно, вы захотите попытаться материализовать запрос, прежде чем пытаться создать объекты InfrStadium.Я перепишу, используя методы расширения, так как я думаю, что будет легче читать.

var stadiums = DbContext.sectors
                        .ToLookup( s => s.TeamId )
                        .Select( g => new InfrStadium( g.Key, g ) )
                        .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...