用 2 Selects 改进这个 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 ,只有一个是 Sum ,另一个是 Count() ,我如何将它们合并到 .1 select 中。

请指教


犯罪嫌疑人X
浏览 85回答 1
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()通过对段求和和计数来填充视图模型。
打开App,查看更多内容
随时随地看视频慕课网APP