Jeff
Jeff

Reputation: 2313

Linq query with count (extension method)

I expect a very simple solution, but I can't for the life of me figure this out...

I am trying to create the LINQ equivalent of this:

SELECT Group, COUNT(*) as GroupCount
FROM table1
WHERE Valid > 0
GROUP BY Group, Project

I have this so far:

var model = _db.table1
    .Where(r => r.Valid > 0)
    .GroupBy(r => new { r.GROUP, r.Project})
    .Select(r => new{ r.GROUP, GroupCount = r.count()};

What is wrong with my query? Visual studio throws and error stating that:

System.Linq.IGrouping' does not contain a definition for 'GROUP' and no extension method 'GROUP' accepting a first argument of type 'System.Linq.IGrouping' could be found (are you missing a using directive or an assembly reference?)

EDIT: Just a note: The above error is given for r.Group in the Select clause.

It also throws an error stating that the count extension method doesn't exist, but I've seen other examples done this way. Maybe I was looking at an example from an old version of LINQ?

EDIT2: Some example data

GroupName    ProjectID    Step    Other Info...
-----------------------------------------------
GroupA     |     1      |   1   | ..............
GroupA     |     1      |   2   |..............
GroupA     |     3      |   1   | ..............
GroupB     |     4      |   1   | ..............
GroupB     |     5      |   1   | ..............
GroupC     |     6      |   1   |..............

Desired result:

 GroupName    Group Count
--------------------------- 
GroupA      |     2
GroupB      |     2
GroupC      |     1

Upvotes: 2

Views: 3895

Answers (3)

Mario S
Mario S

Reputation: 11945

Well, you have following errors in the .Select statement:

  • .count should be .Count (C# is case sensitive)
  • r.GROUP should be r.Key or r.Key.GROUP (.GroupBy() returns an IGrouping<TKey, TElement>)
  • You forgot the last parenthesis in the Select method. (But maybe that was just a typo in the example)

Result:

var model = _db.table1
    .Where(r => r.Valid > 0)
    .GroupBy(r => new { r.GROUP, r.Project })
    .Select(r => new { r.Key.GROUP, GroupCount = r.Count() });

UPDATE:

After the comments and question update; it looks like you are only grouping by group, so that would turn in to something like this to yield the output you requested:

var model = _db.table1
    .Where(r => r.Valid > 0)
    .GroupBy(r => new { r.GROUP }) // First, group only on GROUP
    .Select(r => new 
    { 
        r.Key.GROUP, 
        // Second, group on unique ProjectId's
        GroupCount = r.GroupBy(g => g.Project).Count()
    });

Or simplified:

var model = _db.table1
    .Where(r => r.Valid > 0)
    .GroupBy(r => r.GROUP) // First, group only on GROUP
    .Select(r => new 
    { 
        Group = r.Key, 
        // Second, group on unique ProjectId's
        GroupCount = r.GroupBy(g => g.Project).Count() 
    });

As you asked in the comments, yes, you could say that the values are concatenated in the GroupBy clause. So new { r.GROUP, r.Project } would group all pairs with the same value.

Upvotes: 2

Dennis Traub
Dennis Traub

Reputation: 51634

LINQ queries are case-sensitive. You're trying to access r.GROUP, which probably doesn't exist. Use r.Group instead. Also change r.count() to r.Count(). Here's the corrected code:

var model = _db.table1
    .Where(r => r.Valid > 0)
    .GroupBy(r => new { r.Group, r.Project})
    .Select(r => new{ r.Key, GroupCount = r.Count()};

Upvotes: 1

Corey Adler
Corey Adler

Reputation: 16137

When you're doing the Group By, you're creating a new anonymous type (not of the type you think it is). Thus, when you're doing the select statement, it has no idea what the heck GROUP is.

To mitigate this, follow the 2nd answer located here.

Upvotes: 0

Related Questions