улучшить этот Linq с 2 выбора к той же таблице - PullRequest
0 голосов
/ 26 апреля 2019

Привет, у меня есть этот запрос, который заполняет CompletedWords и CompletedRows потомками, которые имеют статус «Завершено», дело в том, что он идет в 2 раза больше таблицы сегментов вместо 1:

var query = _context.Submodules.Where(t => t.Id == id)
                    .Select(e => new Submodules{
                        Id = e.Id,
                        Name = e.Name,
                        Status = e.Status,
                        Token = e.Token,
                        ModuleId = e.ModuleId,
                        Gender = e.Gender,
                        TotalRows = e.TotalRows,
                        TotalWords = e.TotalWords,
                        CompletedWords = e.Segments.Where(a => a.Status == Abr.Recorded).Sum(y=> y.Wordcount),
                        CompletedRows = e.Segments.Where(a => a.Status == Abr.Recorded).Count()
                    }).ToList();

, что означает:

SELECT t.ID, t.name, t.status, t.token, t.moduleID,
t.gender, t.total_rows AS TotalRows, t.total_words AS TotalWords, 
(
    SELECT SUM(a.wordcount)
    FROM segments AS a
    WHERE (a.status = 1) AND (t.ID = a.submoduleID)
) AS CompletedWords, (
    SELECT COUNT(*)
    FROM segments AS a0
    WHERE (a0.status = 1) AND (t.ID = a0.submoduleID)
) AS CompletedRows
FROM submodules AS t
WHERE t.ID = @__id_0

Как вы можете видеть, чтобы заполнить CompletedWords и Rows, он запускает 2 выбора, где Status == 1, только одна из них Sum, а другая - Count (), как я могу объединить их в .1выберите.
Пожалуйста, совет

1 Ответ

1 голос
/ 26 апреля 2019

Я бы не стал сильно беспокоиться о SQL, который генерирует EF, если вы явно не видите проблему с производительностью. Движки баз данных достаточно искусны для самооптимизации.

Чтобы ответить на ваш вопрос, это должно сработать:

var query = _context.Submodules.Where(t => t.Id == id)
                    .Select(e => new {
                        Id = e.Id,
                        Name = e.Name,
                        Status = e.Status,
                        Token = e.Token,
                        ModuleId = e.ModuleId,
                        Gender = e.Gender,
                        TotalRows = e.TotalRows,
                        TotalWords = e.TotalWords,
                        ComletedSegments = e.Segments
                           .Where(a => a.Status == Abr.Recorded)
                           .Select(y => new { y.Wordcount })
                           .ToList()
                    }).ToList()
                    .Select(e => new Submodules{
                        Id = e.Id,
                        Name = e.Name,
                        Status = e.Status,
                        Token = e.Token,
                        ModuleId = e.ModuleId,
                        Gender = e.Gender,
                        TotalRows = e.TotalRows,
                        TotalWords = e.TotalWords,
                        CompletedWords = e.Sum(y=> y.Wordcount),
                        CompletedRows = e.Count()
                    }).ToList();

Первый запрос выбирает анонимный тип для выбора количества слов из соответствующих завершенных сегментов. ToList() материализует это и выполняет запрос. Для сегментов вы можете не указывать .Select(), хотя это сокращает выбранные данные до нужного нам столбца.

Второй .Select() заполняет модель представления путем суммирования и подсчета сегментов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...