У меня есть таблица со столбцами (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
Примечания: рассмотрите использование DistinctBy, который использует более сложные алгоритмы для выбора отдельных объектов по некоторым критериям.
Из комментариев, которые, как я понимаю, вы работаете над базой данных. Из этого вы должны иметь какой-то контекст.
Таким образом, вы должны быть в состоянии сделать что-то в этом направлении:
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; }
}
На следующем изображении вы сначала получаете исходные данные, а вторая таблица отображает дубликаты, которые будут удалены из вашего источника:
Если есть много дубликатов, то более эффективно это делать непосредственно в 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();
Использовать GroupBy
items.GroupBy(item => new { Name = item.Name, Price = item.Price })
Это сгруппирует их, а затем вы решите, что вы хотите сделать, например, первый или последний.