用2选择到同一张表来改善此Linq

时间:2019-04-26 00:46:17

标签: c# asp.net entity-framework linq

嗨,我有一个查询,其中填充了状态为Completed的Childs的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,一个是它的总和,另一个是Count(),我如何将它们合并到.1 select中。
请指教

1 个答案:

答案 0 :(得分:1)

除非您明确看到性能问题,否则我不会太担心EF生成的SQL。数据库引擎非常擅长自我优化。

但是要回答您的问题,这应该可以:

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()通过对段进行求和和计数来填充视图模型。