基于多个字段查找重复对象的Linq查询且属性为null。

3

我正在尝试基于两个字段查找重复对象,但仅在第三个字段为空的情况下

ItemNumber, Name, Pricebook, Parent
Item1, A, B, <null>
Item2, A, B, Item1
Item3, A, B, <null>
Item4, A, B, Item1
Item5, A, B, Item2

所以在上述列表中,仅有两个重复的项目实际上是Item1和Item3。
var duplicateItemsList =
    from i in items
    group i by new { i.ItemNumber, i.Pricebook, i.Parent } into d
    where d.Count() > 1
    select new { ItemNumber = d.Key.ItemNumber, Pricebook = d.Key.Pricebook, Parent = d.Key.Parent, Count = d.Count() };

我遇到的问题是在Linq查询中检查空字段值。
在上述Linq查询之后,我只想得到一个包含重复的ItemNumber和Pricebook字段值的列表。
2个回答

3

我认为在结果和分组键中不需要使用Parent属性,因为它的值将是null。此外,如果匿名对象的属性名与被赋值属性的名称相同,那么您不需要指定属性名称。

var duplicateItemsList =
    from i in items
    where i.Parent == null
    group i by new { i.Name, i.Pricebook } into d
    where d.Count() > 1
    select new { 
                  d.Key.Name, 
                  d.Key.Pricebook, 
                  Count = d.Count()
               };

同时您可以引入新的范围变量来存储组中的项数。这样,项数将只计算一次:
var duplicateItemsList =
    from i in items
    where i.Parent == null
    group i by new { i.Name, i.Pricebook } into d
    let groupItemsCount = d.Count()
    where groupItemsCount > 1
    select new { 
                  d.Key.Name, 
                  d.Key.Pricebook, 
                  Count = groupItemsCount
               };

更新:正如@Blachshma所指出的那样,您将分组方式从名称改为了项目编号。


1
我不是那个给你点踩的人,但我确实尝试运行了你的代码并且没有得到任何结果。我认为这是因为你在按ItemNumber分组而不是按Name分组。 - Blachshma
无论如何,被接受的答案也是不正确的。@Woodjitsu - 我猜你在问题中错误地写了列名的顺序。在你的问题中,你写道ItemNumber是第一列(它包含“Item1”,“Item2”等),按照它进行分组将始终给出0个结果。 - Blachshma
1
同意 - 目前唯一正确的答案是@lazyberezovsky提供的。 - Blachshma
Blachsma - 是的 - 我刚刚检查了一下,意识到我在问题中所做的是将列名搞错了(itemnumber和name)。不过不会更新问题列,因为那样会使@lazyberezovsky(已更正)的答案代码出错。 - Woodjitsu
1
更改了所选答案以适应原始问题的要求。 - Woodjitsu
显示剩余2条评论

2
var duplicateItemsList =
    from i in items
    where i.Parent == null
    group i by new { i.ItemNumber, i.Pricebook, i.Parent } into d
    where d.Count() > 1
    select new { ItemNumber = d.Key.ItemNumber, Pricebook = d.Key.Pricebook, Parent = d.Key.Parent, Count = d.Count() };

在进行分组和重复检查之前,您可以使用附加的where子句过滤掉只包含null值的项目。


谢谢Kevin,自己摸索了一会儿后找到了解决方法,并得出了相同的答案 - 感谢您的快速回复。我最初尝试在分组之后的第二个where子句中筛选,这显然是错误的。 - Woodjitsu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接