繁体   English   中英

如何在linq中使用分组,不同和一起计数?

[英]How do I use grouping, distinct, and count together in linq?

我有一个ActivityLog表,其中有一个行针对Web应用程序中每个页面上的每个命中。 该表具有以下相关字段:PageTitle,UserName,ActivityDate。 我想添加一个带有GridView的“使用历史记录”页面,该页面具有以下列:页面标题,#命中次数,#唯一用户。 因此,对于应用程序中的每个页面,我们将显示总点击数以及访问该页面的唯一身份用户数。

我尝试了以下linq,从搜索中可以发现,该linq应该可以正常工作:

var ual = (from activityLog in linqMetaData.UserActivityLog
           group activityLog by activityLog.PageTitle into pageGroup
           select new PageUsageStatistics()
           {
               PageTitle = pageGroup.Key,
               NumHits = pageGroup.Count(),
               NumUniqueUsers = pageGroup.Select(x => x.UserName).Distinct().Count()
           });

NumHits返回预期的数目; 但是,NumUniqueUsers返回的是具有匹配的唯一用户总数,而不是每个页面的计数。 因此,如果我有3个用户,每个用户在各自不同的页面上都有1个命中(User1命中Page1,User2命中Page2,而User3命中Page3),则表中的所有三行都将NumUniqueUsers列显示3。 1。

有什么建议么?

谢谢克里斯

编辑-添加生成的SQL:

SELECT [LPA_L1].[PageName], 
       [LPA_L1].[NumHits], 
       [LPA_L1].[NumUniqueUsers] 
FROM 
    (SELECT [LPA_L2].[PageTitle] AS [PageName], 
            [LPA_L2].[LPAV_] AS [NumHits], 
            (SELECT COUNT(*) AS [LPAV_] 
             FROM 
                 (SELECT DISTINCT [LPA_L2].[UserPrincipleName] 
                  FROM [USIC].[dbo].[UserActivityLog]  [LPA_L2]  
                 ) [LPA_L3]) AS [NumUniqueUsers] 
     FROM 
         (SELECT [LPLA_1].[PageTitle], 
                 COUNT(*) AS [LPAV_] 
          FROM [USIC].[dbo].[UserActivityLog]  [LPLA_1]   
          GROUP BY [LPLA_1].[PageTitle]
         ) [LPA_L2]
    ) [LPA_L1] 
ORDER BY [LPA_L1].[PageName] ASC

“ 3个用户,每个用户在3页中的每一个上都有1个匹配项”

我将其解释为意味着您的日志如下所示:

  • 用户1-第1页
  • 用户1-第2页
  • 用户1-第3页
  • 用户2-第1页
  • 用户2-第2页
  • 用户2-第3页
  • 用户3-第1页
  • 用户3-第2页
  • 用户3-第3页

在这种情况下,每个页面确实有3个唯一用户,因此您的代码是正确的

尝试添加此扩展方法:

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> knownKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        if (knownKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}

并像这样使用它:

NumUniqueUsers = pageGroup.DistinctBy(x => x.UserName).Count();

很难说DISTINCT在哪里迷路了。 也许LinqToSql正在查询翻译中删除它。 查看生成的sql将确认。

如果Distinct正在(意外地)被LinqToSql丢弃,则这是写该部分查询的另一种方法。

NumUniqueUsers = pageGroup.GroupBy(x => x.UserName).Count()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM