0

I'm trying to achieve the following in LINQ (EF6):

SELECT count(A), sum(B), average(C)
FROM TableA,
LEFT JOIN TableB ON ...
LEFT JOIN TableC ON ...
WHERE
    (very complicated conditions)

The C# code looks like following:

IQueryable<Entity> = dbSet
    .Include(e => e.entityB)
    .Include(e => e.EntityC)
    .Where( <very complicated conditions> );

How can I apply multiple aggregate functions on different fields? Specifically, in a way, which won't cause the complicated conditions to be copied over and over in resulting query?

Spook
  • 25,318
  • 18
  • 90
  • 167
  • please specify a column name sum(B) to sum(b.Qty). same for average(C) – sebu Jul 17 '17 at 12:19
  • You can check this link: https://stackoverflow.com/questions/3414080/using-groupby-count-and-sum-in-linq-lambda-expressions – sebu Jul 17 '17 at 12:36

1 Answers1

11

You can use the group by constant trick to get all the aggregates with single SQL query (and shared complicated filter):

var result = dbSet
    .Where( <very complicated conditions> )
    .GroupBy(e => 1) // aribitrary value
    .Select(g => new
    {
        CountA = g.Count(),
        SumB = g.Sum(e => e.EntityB.PropertyB),
        AverageC = g.Average(e => e.EntityC.PropertyC),
    })
    .FirstOrDefault();
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • It's probably easier for people to grasp using bool instead of int. In other words, "collection.GroupBy(=>true).Select(all=>new ( Sum=all.Sum(), Avg = all.Average(). }) –  Jun 16 '22 at 08:35