简体   繁体   English

LINQ with GROUP BY和HAVING COUNT

[英]LINQ with GROUP BY and HAVING COUNT

I'd like to understand what I am doing wrong with my GROUP BY query in Linq. 我想了解我在Linq的GROUP BY查询中做错了什么。 I've tried many examples (ie Linq with group by having count ), but I still get more results (as is the WHERE is skipped). 我已经尝试了很多例子(例如Linq与group计数 ),但我仍然得到更多结果(因为跳过了WHERE )。 My code is like this: 我的代码是这样的:

var test = session.Query<SomeClass>()
                  .GroupBy(c => new { c.Var1, c.Var2, c.Var3 })
                  .Where(g => g.Count() > 1)
                  .Select(g => g.Key.Var3)
                  .ToList();

This gives 229 results (all records). 这给出了229个结果(所有记录)。 The query that I'd like to build in Linq is: 我想在Linq中构建的查询是:

SELECT Var3
FROM myTable
GROUP BY Var1, Var2, Var3
HAVING COUNT(*) > 1

Somehow, the query is giving me 27 results, but the Linq expression gives me 229 (all). 不知何故,查询给了我27个结果,但Linq表达式给了我229(全部)。 When I replace the where/select part of the Linq expression to the following, I do get a list with counts that are 2 or higher: 当我将Linq表达式的where / select部分替换为以下内容时,我会得到一个计数为2或更高的列表:

.Select(g => new { Item = g.Key, Count = g.Count() })

But I dont want a list with items (and counts) and having to go through that list, I'd like to have the HAVING part work in the Linq expression... 但我不想要一个包含项目(和计数)的列表并且必须通过该列表,我希望HAVING部分在Linq表达式中工作...

Edit 2: If you take a look at LINQ Group By Multiple fields -Syntax help , this also works for me. 编辑2:如果您看一下LINQ Group By Multiple字段-Syntax帮助 ,这对我也有用 However, I'll get a list of objects with Var1, Var2, Var3 and Count. 但是,我将获得Var1,Var2,Var3和Count的对象列表。 Of this list, I only want to Var3 of the objects with a Count higher than 1. 在这个列表中,我只想要Count3大于1的Var3。

Anyone who can point me in the right direction? 谁可以指出我正确的方向?

Edit 1: As I said in my introduction, the question Linq with group by having count is not answering my problem. 编辑1:正如我在我的介绍中所说, Linq与群体一起计算的问题并没有回答我的问题。 If I use this code, I still have a set of 229 results instead of the 27 that are actually "duplicated" (meaning, after the group having a count of more than 1). 如果我使用这个代码,我仍然有一组229个结果而不是27个实际上是“重复”的结果(意思是,在计数超过1的组之后)。

Edit 3: I am using the following at this moment. 编辑3:我现在正在使用以下内容。 I needs two statements, and that I think is weird, but as stated before, this seems to be the only way to select only the records having count > 1. 我需要两个语句,我认为这很奇怪,但如前所述,这似乎是仅选择count> 1的记录的唯一方法。

var querygroup = session.Query<SomeClass>()
                        .GroupBy(e => new { e.Var1, e.Var2, e.Var3 })
                        .Select(s => new { s.Key.Var1, s.Key.Var2, s.Key.Var3, Count = s.Count() })
                        .ToList();

var duplicates = querygroup.Where(g => g.Count > 1)
                           .Select(g => new SomeClass() { Var1 = g.Var1, Var2 = g.Var2, Var3 = g.Var3})
                           .ToList();

Note that instead of selecting only Var3, I decided to select the values Var1 and Var2 aswell and store them in the SomeClass(). 请注意,我决定选择值Var1和Var2,而不是仅选择Var3,并将它们存储在SomeClass()中。 This is just an addition, selecting everything doesn't help with creating 1 statement to get this selection. 这只是一个补充,选择所有内容并没有帮助创建1个语句来获得此选择。

Edit 4: I can ofcourse take the .Where.. part in the duplicates variable and add it to the querygroup statement, thus making the whole one statement. 编辑4:我可以在duplicates变量中使用.Where..部分并将其添加到querygroup语句中,从而创建整个语句。 Success? 成功? Seems overkill but at least it works. 似乎矫枉过正,但至少它有效。

If anyone can find out why I need 2 statements, please elaborate :) 如果有人能找出我需要2个陈述的原因,请详细说明:)

Try this 试试这个

var test = session.Query<SomeClass>()
                  .GroupBy(c => new { c.Var1, c.Var2, c.Var3 })
                  .Select(d=> new { var1 = d.Key.var1,var2 = d.Key.var2,var3=d.Key.var3,records = d.ToList()})
                  .Where(e => e.records.Count() > 1)
                  .Select(g => g.Var3)
                  .ToList();

You can try this in Linqpad . 你可以在Linqpad中试试这个。 I changed the table and column name of your query to match against my own DB: 我更改了查询的表和列名称以匹配我自己的数据库:

Levels
.GroupBy(c => new { c.CourseGuid, c.ModuleName })
.Where(g => g.Count() > 10)
.Select(g => g.Key.CourseGuid)

This was the SQL query it produced: 这是它生成的SQL查询:

-- Region Parameters
DECLARE @p0 Int = 10
-- EndRegion
SELECT [t1].[CourseGuid]
FROM (
    SELECT COUNT(*) AS [value], [t0].[CourseGuid]
    FROM [xrt].[Levels] AS [t0]
    GROUP BY [t0].[CourseGuid], [t0].[ModuleName]
    ) AS [t1]
WHERE [t1].[value] > @p0

Not one with HAVING COUNT but with WHERE instead, and functionally identical. 不是HAVING COUNT而是WHERE而且功能相同。 Playing with the @p0 parameters shows that the output gets filtered properly. 使用@ p0参数显示输出已正确过滤。

I recommend you try with Linqpad to see what your query does against your data. 我建议您尝试使用Linqpad查看您的查询对您的数据做了什么。

So, the answer to my question: 那么,我的问题的答案:

var duplicates = session.Query<SomeClass>()
                        .GroupBy(e => new { e.Var1, e.Var2, e.Var3 })
                        .Select(s => new { s.Key.Var1, s.Key.Var2, s.Key.Var3, Count = s.Count() })
                        .ToList()
                        .Where(g => g.Count > 1)
                        .Select(g => new SomeClass() { Var1 = g.Var1, Var2 = g.Var2, Var3 = g.Var3})
                        .ToList();

Seems a bit overkill, I feel like it could be smaller, so if anyone likes to comment on that... 似乎有点矫枉过正,我觉得它可能更小,所以如果有人喜欢对此发表评论......

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

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