【问题标题】:How to use distinct with group by in Linq to SQL如何在 Linq to SQL 中使用 distinct 和 group by
【发布时间】:2011-05-23 08:12:09
【问题描述】:

我正在尝试将以下 sql 转换为 Linq 2 SQL:

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

这是我的代码:

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

当我运行代码时,我不断收到 Invalid GroupID。 有任何想法吗?似乎不同的是把事情搞砸了..

这里是生成的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]

【问题讨论】:

  • @Basiclife:FUBAR 是什么?在 SQL 中,NULL 不等于任何东西,包括 NULL。如果两者都是 NULL,t1.GroupID = t2.GroupId 仍然是错误的。这是关联两个 NULL 字段的唯一方法。

标签: c# .net linq linq-to-sql


【解决方案1】:

我认为 Basiclife 很接近,但检查 id 是否为空可能不是问题或不够,您应该在进行组之前检查以确保它不为空,因为您说它是一个可为空的字段。否则它看起来是正确的,如果您遇到问题,您可能有错误的数据,或者它是 Linq to SQL 的错误或未完全实现的功能,您可能想尝试 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()
        };

【讨论】:

    【解决方案2】:

    根据这篇文章,您的代码看起来是正确的:

    LINQ to SQL using GROUP BY and COUNT(DISTINCT)

    您是否尝试过检查生成的 SQL?

    【讨论】:

    • 是的,请看我的原帖看看生成的无效sql。
    【解决方案3】:

    在生成的 SQL 中似乎有一大堆 goop 来处理 GroupID 为 NULL。如果有这种可能?如果不是,请尝试更改定义以使其 NOT NULL。

    【讨论】:

      【解决方案4】:

      尝试使用 where 子句来消除连接后的虚假 ID...

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

      【讨论】:

      • 出于兴趣,是否有任何 Id 列可以故意为空?另外,您能否根据调试器(不是声明)告诉我们 ProcessRoundIssueInstance 的数据类型。谢谢
      • 是的,GroupID 可以为空,但我也尝试了另一个不可为空的列。 System.Data.Linq.Table
      【解决方案5】:

      您确定正确的数据库完整性吗?无论如何,也许你应该试试这个: 我不知道一个组怎么会是空的,但这似乎是你的问题。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-18
        • 2010-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多