tags:

views:

40

answers:

1

I would like to execute a Linq to Sql statement that captures the count and average in a (filtered) set of data. What I have works, but it requires two queries to the database when it should be possible in one query.

Interestingly enough, I can get one query to be emitted when I use a group by clause.

For example:

select count(*), avg(duration) from events

My linq looks like this:

var x = from e in db.events
        select e;
x = from i in x
    where i.NAME == "foo"
    select i;

return new {
    count = x.Count(),
    avgDuration = x.Average(e => e.Duration)
    };

With that code I get two queries:

SELECT AVG([t0].[DURATION]) AS [value] FROM [dbo].[EVENTS] AS [t0]

and

SELECT COUNT(*) AS [value] FROM [dbo].[EVENTS] AS [t0]

Is there another way?

+3  A: 

The best I can get is a nested subquery:

var x = from e in db.events 
        group e by 1 into grp
        select new { 
            count = grp.Count(), 
            avgDuration = grp.Average(x => x.Duration) }

According to LINQPad, this will output the SQL:

DECLARE @p0 Int = 1

SELECT COUNT(*) AS [count], AVG([t1].[Amount]) AS [avgDuration]
FROM (
    SELECT @p0 AS [value], [t0].[Duration]
    FROM Events AS [t0]
    ) AS [t1]
GROUP BY [t1].[value]
gordonml
wow, linq never ceases to surprise me for what can be done, the sql used to get it and the interesting code crafted to get the job done+1
Gavin