12

I'm trying to convert the following sql to Linq 2 SQL:

select groupId, count(distinct(userId)) from processroundissueinstance 
group by groupId

Here is my code:

var q = from i in ProcessRoundIssueInstance
    group i by i.GroupID into g
    select new
    {
        Key = g.Key,
        Count = g.Select(x => x.UserID).Distinct().Count()
    };

When I run the code, I keep getting Invalid GroupID. Any ideas? Seems the distinct is screwing things up..

Here is the generated sql:

SELECT [t1].[GroupID] AS [Key], (
SELECT COUNT(*)
FROM (
    SELECT DISTINCT [t2].[UserID]
    FROM [ProcessRoundIssueInstance] AS [t2]
    WHERE (([t1].[GroupID] IS NULL) AND ([t2].[GroupID] IS NULL)) 
       OR (([t1].[GroupID] IS NOT NULL) 
            AND ([t2].[GroupID] IS NOT NULL) 
            AND ([t1].[GroupID] = [t2].[GroupID]))
    ) AS [t3]
) AS [Count]
FROM (
    SELECT [t0].[GroupID]
    FROM [ProcessRoundIssueInstance] AS [t0]
    GROUP BY [t0].[GroupID]
    ) AS [t1]
James Curran
  • 101,701
  • 37
  • 181
  • 258
Marco
  • 2,453
  • 3
  • 25
  • 35
  • @Basiclife: What's FUBAR about that? In SQL NULL is not equal to anything, including NULL. If both were NULL, `t1.GroupID = t2.GroupId` would still be false. That's that only way to associate two NULL fields. – James Curran Aug 26 '10 at 20:52

5 Answers5

5

I think Basiclife is close, but checking if the id is empty may not be the issue or enough, you should check to make sure it is not null before doing the group since you said it is a nullable field. Otherwise it looks right, and if you are having issues you may have bad data, or it is a bug or not fully implemented feature of Linq to SQL, and you may want to try Linq to Entity.

var q = from i in ProcessRoundIssueInstance
        where i.GroupID != null
        && i.GroupID != string.Empty
        group i by i.GroupID into g        
        select new
        {
            Key = g.Key,
            Count = g.Select(x => x.UserID).Distinct().Count()
        };
Rodney S. Foley
  • 10,190
  • 12
  • 48
  • 66
0

According to this post, your code looks correct:

LINQ to SQL using GROUP BY and COUNT(DISTINCT)

Have you tried inspecting the SQL that is generated?

Community
  • 1
  • 1
Dave Swersky
  • 34,502
  • 9
  • 78
  • 118
0

There appears to be a whole bunch of goop in the generated SQL to deal with the GroupID being NULL. If that a possiblity? IF not, try changing the definition to make it NOT NULL.

James Curran
  • 101,701
  • 37
  • 181
  • 258
0

Try a where clause to eliminate spurious Ids after the join...

var q = from i in ProcessRoundIssueInstance
    where i.GroupID != ""
    group i by i.GroupID into g
    select new
    {
        Key = g.Key,
        Count = g.Select(x => x.UserID).Distinct().Count()
    };
Basic
  • 26,321
  • 24
  • 115
  • 201
  • Out of interest, is there any Id column nullable intentionally? Also, can you tell us the data type for ProcessRoundIssueInstance according to the debugger (not declaration). Thanks – Basic Aug 26 '10 at 21:24
  • Yes, the GroupID is nullable but I also tried on another non-nullable column. System.Data.Linq.Table – Marco Aug 26 '10 at 21:27
0

Are you certain of correct database integrity? Anyway maybe you should try this: I don't know how a group would be empty, but that seems to be your problem.

ProcessRoundIssueInstance.Where(i => i.GroupId != null)
    .GroupBy(i => i.GroupID)
    .Select(group => new 
                    { 
                      Key = group.Key,
                      Count = group.SingleOrDefault() == null ? 0 : 
                              group.SingleOrDefault().Select( item => item.UserID).Distinct().Count() 
                     });
Marcel Valdez Orozco
  • 2,985
  • 1
  • 25
  • 24