单个Linq-to-Entities查询中的多个SQL聚合函数

Dre*_*kes 22 .net linq-to-entities entity-framework

在SQL中,您可以在单个数据库查询中表达多个聚合,如下所示:

SELECT MIN(p.x), MAX(p.x), MIN(p.y), MAX(p.y)
FROM   Places p JOIN Logs l on p.Id = l.PlaceId
WHERE  l.OwnerId = @OwnerId
Run Code Online (Sandbox Code Playgroud)

是否有可能使用Linq-to-Entities做同等的事情?我发现了一个类似的问题,表明Linq-to-SQL不可能,但我想我不需要四次往返数据库进行上述操作.

小智 25

假设您有以下SQL语句:

  select sum(A), max(B), avg(C) from TBL group by D
Run Code Online (Sandbox Code Playgroud)

在C#中试试这个:

  from t in table
  group t by D
  into g
  select new {
     s = g.Sum(x => x.A),
     m = g.Max(x => x.B),
     a = g.Average(x => x.C)
  }
Run Code Online (Sandbox Code Playgroud)

- 或在VB中: -

  from t in TBL
  group t by key = D
  into g = group
  select s = g.Sum(function(x) x.A),
       m = g.Max(function(x) x.B),
       a = g.Average(function(x) x.C)
Run Code Online (Sandbox Code Playgroud)

显而易见的,在VB中将是:

  aggregate t in TBL into s = Sum(t.A), m = Max(t.B), a = Average(t.C)
Run Code Online (Sandbox Code Playgroud)

虽然它会给出相同的结果,但它会产生更高的成本,因为它会发出多个SQL select语句,每个聚合函数一个,即它将在多次传递中运行.第一种语法提供了一个(相当复杂但有效)的SQL语句,它对数据库进行单次传递.

PS.如果您没有要分组的键(即,您需要一行作为结果,覆盖整个数据集),请使用常量,如下所示:

  from t in TBL
  group t by key = 0
  into g = group
  select s = g.Sum(function(x) x.A),
       m = g.Max(function(x) x.B),
       a = g.Average(function(x) x.C)
Run Code Online (Sandbox Code Playgroud)