Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework multiple counts with a single query

Sorry if this has been asked, but how can I improve the following with a single call to the database?

var statsModel = new
{
     Total = _db.Messages.Count(),
     Approved = _db.Messages.Count(x => x.Approved),
     Rejected = _db.Messages.Count(x => !x.Approved),
};
like image 324
TYRONEMICHAEL Avatar asked Jan 17 '12 12:01

TYRONEMICHAEL


3 Answers

This might help:

var statsModel =(
        from message in _db.Messages
        group message by 1 into g
        select new
        {
            Total = g.Count(),
            Approved =g.Count (x =>x.Approved),
            Rejected =g.Count (x =>!x.Approved)
        }
    ).FirstOrDefault();
like image 186
Arion Avatar answered Nov 15 '22 00:11

Arion


First of all you can compute the Rejected by Total and Accepted like this:

Rejected = Total - Approved

And for further improvement you can compute both of them in one shot;

from m in _db.Messages
let Total =  _db.Messages.Count()
let Accept = _db.Messages.Count(x => x.Approved == true)
select new {Total , Accept})

UPDATE: a simple hack for now : just take the first row

(from m in _db.Messages
let Total =  _db.Messages.Count()
let Accept = _db.Messages.Count(x => x.Approved == true)
select new {Total , Accept}).Take(1);

But I'm looking for a cleaner one

like image 34
Jahan Zinedine Avatar answered Nov 15 '22 00:11

Jahan Zinedine


In C# (rather than LINQ query), async syntax:

var statsModel = await _db.Messages
.GroupBy(m => 1, (g, mm) => new
{
    Total = mm.Count(),
    Approved = mm.Count(m => m.Approved),
    Rejected = mm.Count(m => !m.Approved)
})
.SingleAsync();
like image 44
Chris Moschini Avatar answered Nov 15 '22 00:11

Chris Moschini