C# 如何在没有主键的情况下删除重复项(不同的值)

C# 如何在没有主键的情况下删除重复项(不同的值),c#,linq,linq-to-sql,lambda,C#,Linq,Linq To Sql,Lambda,我有一个包含列(ItemID、Name、Price)的表 项目列表中填充了重复的项目 例如: -------------------------------------- ItemID Name Price -------------------------------------- 1 Bangles 100 2 Saree 200 3

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

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

例如:

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

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

方法是根据条件对项目进行分组,然后选择每组中的第一个项目

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

注释:考虑使用一种更高级的算法来根据某些标准选择不同的对象。 想法是根据标准对项目进行分组,然后选择每组中的第一个项目

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

注释:考虑使用一种更高级的算法来根据某些标准选择不同的对象。 使用GroupBy

items.GroupBy(item => new { Name = item.Name, Price = item.Price })
这将对它们进行分组,然后您决定要做什么,例如,获取第一个或最后一个

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

这将对它们进行分组,然后您决定要执行的操作,例如获取第一个或最后一个。

如果存在大量重复项,则直接在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();

如果存在大量重复项,则直接在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();

根据我的评论,我认为你正在处理一个数据库。因此,您应该有某种可用的上下文

因此,您应该能够按照以下思路做一些事情:

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; }
}
void Main()
{
//虚拟数据
var items=新列表()
{
新项目{Id=1,Name=“Bangles”,Price=100},
新项目{Id=2,Name=“Saree”,价格=200},
新项目{Id=3,Name=“Shoes”,Price=150},
新项目{Id=4,Name=“Bangles”,Price=100},
新项目{Id=5,Name=“Shoes”,价格=150}
};
//选择重复项目
var itemsToDelete=items.GroupBy(i=>new{i.Name,i.Price});
//删除重复的项目
context.DeleteAllOnsubmit(itemsToDelete);
//拯救
SaveChanges();
}
公共类项目
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共整数价格{get;set;}
}
在下图中,首先是原始数据,第二个表显示将从源中删除的重复数据:


根据我的评论,您正在处理数据库。因此,您应该有某种可用的上下文

因此,您应该能够按照以下思路做一些事情:

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; }
}
void Main()
{
//虚拟数据
var items=新列表()
{
新项目{Id=1,Name=“Bangles”,Price=100},
新项目{Id=2,Name=“Saree”,价格=200},
新项目{Id=3,Name=“Shoes”,Price=150},
新项目{Id=4,Name=“Bangles”,Price=100},
新项目{Id=5,Name=“Shoes”,价格=150}
};
//选择重复项目
var itemsToDelete=items.GroupBy(i=>new{i.Name,i.Price});
//删除重复的项目
context.DeleteAllOnsubmit(itemsToDelete);
//拯救
SaveChanges();
}
公共类项目
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共整数价格{get;set;}
}
在下图中,首先是原始数据,第二个表显示将从源中删除的重复数据:



您知道这些实际上并不是重复的,因为“手镯”和“鞋子”的两个条目有不同的条目ID,对吗?是的,条目ID是不同的。但我的问题是没有主键的重复项请添加预期的输出/结果以及基于SQL的可接受答案可能会对您有所帮助是的,我想使用实体框架来实现这一点您知道这些实际上并不重复,因为“手镯”和“鞋”的两个条目具有不同的ItemID,对吗?是的,条目ID不同。但我的问题是没有主键的重复请添加预期的输出/结果以及基于SQL的可接受答案可能会对您有所帮助是的,我想使用实体框架来准确地完成这一点,但我想从table@SrinivasNaidu您在问题中提到了如何仅使用linq两个删除列表中的重复项不考虑主键的列。这更像是一个SQL或ORM问题。为了过滤返回的列表,也许他可以简单地使用
var-differentitems=items.Select(i=>new{i.Name,i.Price,}).Distinct()。目前尚不清楚他想如何处理
Name
Price
@JeppeStigNielsen-yeap冲突的情况,但他可能也需要
id
s,对此不确定。OP希望更新数据库中的表在我的情况下,我会更新价格和名称。如果价格和名称已经存在,那么它将是重复的,因此我想删除该重复项,但我想从中删除重复记录table@SrinivasNaidu您在问题中提到了如何仅使用linq两列删除列表中的重复项,而不考虑主键。这更像是一个SQL或ORM问题。为了过滤返回的列表,也许他可以简单地使用
var-differentitems=items.Select(i=>new{i.Name,i.Price,}).Distinct()。目前尚不清楚他想如何处理
Name
Price
@JeppeStigNielsen-yeap冲突的情况,但他可能也需要
id
s,对此不确定。OP希望更新数据库中的表在我的情况下,我会更新价格和名称。如果价格和na