使用许多子查询重构LINQ to SQL/Entities查询

Dis*_*ile 5 c# linq-to-entities entity-framework linq-to-sql

我有以下LINQ to Entities查询,它有许多子查询来获取一些聚合数据:

var systems = from s in db.Systems
              orderby s.Name
              select new SystemSummary
              {
                  Id = s.Id,
                  Code = s.Code,
                  Name = s.Name,
                  LastException = (
                      from a in s.Applications
                      from e in a.Summaries
                      select e.CreationDate
                  ).Max(),
                  TodaysExceptions = (
                      from a in s.Applications
                      from e in a.Summaries
                      where e.CreationDate >= today && e.CreationDate < tomorrow
                      select e
                  ).Count(),
                  /* SNIP - 10-15 more subqueries */                              
              };
Run Code Online (Sandbox Code Playgroud)

我将查询缩短为仅包含2个子查询,但可能会有大约10-15个子查询.有没有办法可以重构查询来清理代码?我不是在寻求性能提升.我想通过将子查询放入单独的方法来清理代码,同时仍然确保它是对数据库的单个调用.这可能吗?

Sae*_*iri 2

我只能通过类似这样的方式最小化其长度(通过let在原始查询中使用关键字):

var subQuery =    from a in s.Applications
                  from e in a.Summaries
                  select e;
Run Code Online (Sandbox Code Playgroud)

您还可以进行一些重构,例如:

subQuery.Count(e=>e.CreationDate >= today && e.CreationDate < tomorrow);

subQuery.max(e=>e.CreationDate);
Run Code Online (Sandbox Code Playgroud)

事实上,使用点符号并将查询移动到相关函数而不是额外的where子句。

并在您的查询中使用subQuery

          from s in db.Systems
          orderby s.Name
          let subQuery =    from a in s.Applications
                  from e in a.Summaries
                  select e
          select new SystemSummary
          {
              Id = s.Id,
              Code = s.Code,
              Name = s.Name,
              LastException = subQuery.max(e=>e.CreationDate),
              TodaysExceptions = subQuery.Count(e=>e.CreationDate >= today 
                                          && e.CreationDate < tomorrow),
              /* SNIP - 10-15 more subqueries */                              
          };
Run Code Online (Sandbox Code Playgroud)

这仍然是对 db 的单个调用。