20

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),
};
2
  • 1
    at least Rejected = Total - Approved Commented Jan 17, 2012 at 12:36
  • I mean I could easily return all Messages and filter down form there, but I might have thousands of messages. Returning the entire table would be an intense query, and thats why I just need to return the count. Commented Jan 17, 2012 at 12:42

3 Answers 3

14

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();
Sign up to request clarification or add additional context in comments.

Comments

11

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

1 Comment

Last question related to this. It is working correctly, but returning the {Total,Accept} for each message. So what I did was "from m in _db.Messages let Total = _db.Messages.Count() let Accept = _db.Messages.Count(x => x.Approved == true) select new {Total , Accept}).FirstOrDefaul();
5

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();

2 Comments

It fails if table is empty, so SingleOrDefault and an additonal if is needed.
@kemsky That depends on whether an empty table is Exceptional in your Application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.