【问题标题】:Linq query to find duplicate objects based on multiple fields AND property is nullLinq查询基于多个字段和属性查找重复对象为空
【发布时间】:2012-11-26 17:47:31
【问题描述】:

我正在尝试根据 2 个字段定位重复对象,但仅限于第 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

所以在上面的列表中,只有 2 个重复项实际上是 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 字段值的列表。

【问题讨论】:

    标签: c# .net linq


    【解决方案1】:

    我认为您在结果和摸索键中不需要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
                   };
    

    UPDATE 正如@Blachshma 指出的那样,您按 ItemNumber 而不是 Name 进行分组

    【讨论】:

    • 我不是反对者,但我确实尝试运行您的代码并得到 0 个结果。我认为这是因为您在 ItemNumber 而不是 Name 上分组
    • @Blachshma 同意,分组应该是 NamePricebook - 我只是从问题中复制粘贴了那部分
    • @Woodjitsu 按ItemNumber 分组不适合您,因为它会创建五个不同的组,其中包含{Item1, B}, {Item2, B} etc 之类的键。你真正需要的是关键{A, B}
    • 同意 - 目前唯一正确的答案是 @lazyberezovsky 的
    • 更改了选择的答案以适合最初提出的问题
    【解决方案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 子句进行重复检查。

    【讨论】:

    • 欢呼凯文,在经过更多的尝试后,我自己想出了这个,并想出了相同的解决方案 - 为及时回复欢呼。我最初试图在分组后的第二个 where 子句中进行过滤,这显然是错误的
    猜你喜欢
    • 2017-05-13
    • 1970-01-01
    • 2011-08-01
    • 2014-02-12
    • 1970-01-01
    • 2019-08-27
    • 2018-05-11
    • 2012-10-13
    • 1970-01-01
    相关资源
    最近更新 更多