如何使用主键删除重复项(不同的值)

时间:2014-05-19 09:18:41

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

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

项目清单中填充了重复的项目。

例如:

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

如何使用linq删除列表中的重复项,而不管主键是什么?

4 个答案:

答案 0 :(得分:4)

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

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,它使用更高级的算法按某些条件选择不同的对象。

答案 1 :(得分:0)

使用GroupBy

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

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

答案 2 :(得分:0)

如果有很多重复项,那么直接在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();

答案 3 :(得分:0)

从我的评论中,你正在研究一个数据库。从这里你应该有一些可用的上下文。

所以你应该能够做到这一点:

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; }
}

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

enter image description here