Как удалить дубликаты (различные значения) без первичного ключа

1

У меня есть таблица со столбцами (ItemID, Name, Price).

Список элементов заполняется дублируемыми элементами.

Например:

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

Как удалить дубликаты в списке, используя linq, только два столбца, независимо от первичного ключа?

Теги:
linq
lambda
linq-to-sql

4 ответа

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, который использует более сложные алгоритмы для выбора отдельных объектов по некоторым критериям.

  • 0
    Но я хочу удалить дубликаты записей из таблицы
  • 0
    @SrinivasNaidu вы упомянули в вопросе Как удалить дубликаты в списке, используя linq только два столбца, независимо от первичного ключа . Это больше вопрос SQL или ORM.
Показать ещё 4 комментария
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; }
}

На следующем изображении вы сначала получаете исходные данные, а вторая таблица отображает дубликаты, которые будут удалены из вашего источника:

Изображение 174551

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();
0

Использовать GroupBy

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

Это сгруппирует их, а затем вы решите, что вы хотите сделать, например, первый или последний.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню