【问题标题】:How to remove duplicates (distinct values) with out primary key如何在没有主键的情况下删除重复项(不同的值)
【发布时间】:2014-05-19 09:18:40
【问题描述】:

我有一个包含列(ItemID、Name、Price)的表格。

项目列表中填充了重复项目。

例如:

--------------------------------------
ItemID          Name          Price
--------------------------------------
1               Bangles       100   
2               Saree         200   
3               Shoes         150   
4               Bangles       100   
5               Shoes         150  

如何使用 linq 删除列表中的重复项,仅使用两列而不考虑主键?

【问题讨论】:

  • 您知道这些实际上并不是重复的,因为“手镯”和“鞋子”的两个条目具有不同的 ItemID,对吧?
  • 是的,项目 ID 不同。但我的问题是没有主键的重复项
  • 请同时添加预期的输出/结果
  • this question 接受的基于 SQL 的答案可能会对您有所帮助
  • 是的,我想完全使用实体框架来做到这一点

标签: c# linq linq-to-sql lambda


【解决方案1】:

想法是按条件对项目进行分组,然后选择每个组中的第一个项目。

var distinctItems = items.GroupBy(i => new{i.Name, i.Price})
                         .Select(g => g.First());

这是完整的例子:

var items = new[]{
                    new Item{Id = 1, Name = "Bangles", Price = 100},
                    new Item{Id = 2, Name = "Saree",   Price = 200},
                    new Item{Id = 3, Name = "Shoes",   Price = 150},
                    new Item{Id = 4, Name = "Bangles", Price = 100},
                    new Item{Id = 5, Name = "Shoes",   Price = 150}
                 };


var distinctItems = items.GroupBy(i => new{i.Name, i.Price})
                         .Select(g => g.First());

foreach (var item in distinctItems)
{
    Console.WriteLine ("Name: {0} Price: {1}", item.Name, item.Price);
}   

打印:

Name: Bangles Price: 100
Name: Saree Price: 200
Name: Shoes Price: 150

注意:考虑使用DistinctBy,它使用更高级的算法根据某些标准选择不同的对象。

【讨论】:

  • 但我想从表中删除重复记录
  • @SrinivasNaidu 您在问题如何删除 list 中的重复项仅使用 linq 仅两列而不考虑主键。这更像是一个 SQL 或 ORM 问题。
  • 为了过滤返回的列表,也许他可以简单地使用var distinctItems = items.Select(i => new{ i.Name, i.Price, }).Distinct();。目前尚不清楚他想如何处理Name 与冲突Price 重复的情况。
  • @JeppeStigNielsen 是的,但可能他也需要ids,不确定。 OP 想要更新数据库中的表
  • 就我而言,我将更新价格和名称。如果价格和名称已经存在,那么它将是重复的,所以我想删除那个重复
【解决方案2】:

使用分组方式

items.GroupBy(item => new { Name = item.Name, Price = item.Price })

这会将它们分组,然后您决定要做什么,例如获得第一个或最后一个。

【讨论】:

    【解决方案3】:

    如果有很多重复,那么直接在 SQL 中执行此操作效率更高,但如果您想使用 Linq 执行此操作,则可以执行以下操作:

    // Group and count the items in group
    var grouped = (from r in dc.Items group r by new { r.Name, r.Price} into results
      select new { Count = results.Count(), results = results.ToList()} );
    
    // select only the groups with duplicates
    var itemsWithDuplicates = (from r in grouped where r.Count > 1 select r);
    
    // Ignore the first item in each group
    var duplicatesGrouped = (from r in itemsWithDuplicates select r.results.Skip(1));
    
    //UnGroup them
    var duplicates = duplicatesGrouped.SelectMany(r=>r);
    

    然后大概你可以使用类似的东西删除它们

    dc.Items.DeleteAllOnSubmit(duplicates);
    dc.SubmitChanges();
    

    【讨论】:

      【解决方案4】:

      从 cmets 我认为您正在处理数据库。从这里你应该有某种可用的上下文。

      所以你应该能够按照以下方式做一些事情:

      void Main()
      {
          //dummy data
          var items = new List<Item>()
                      {
                          new Item{Id =1, Name = "Bangles", Price=100},
                          new Item{Id =2, Name = "Saree",   Price=200},
                          new Item{Id =3, Name = "Shoes",   Price=150},
                          new Item{Id =4, Name = "Bangles", Price=100},
                          new Item{Id =5, Name = "Shoes",   Price=150}
                       };
          //select duplicate items         
          var itemsToDelete = items.GroupBy (i => new { i.Name, i.Price}).SelectMany(x => x.Skip(1));
          //delete duplicate items
          context.DeleteAllOnsubmit(itemsToDelete);
          //Save
          context.SaveChanges();
      
      }
      
      public class Item
      {
          public int Id { get; set; }
          public string Name { get; set; }
          public int Price { get; set; }
      }
      

      在下图中,您首先拥有原始数据,第二个表格显示将从您的源中删除的重复数据:

      【讨论】:

        猜你喜欢
        • 2015-06-14
        • 2014-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-27
        • 1970-01-01
        • 2022-01-12
        • 2011-11-07
        相关资源
        最近更新 更多