Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ: Select all from each group except the first item

It is easy to select the first of each group:

        var firstOfEachGroup = dbContext.Measurements
            .OrderByDescending(m => m.MeasurementId)
            .GroupBy(m => new { m.SomeColumn })
            .Where(g => g.Count() > 1)
            .Select(g => g.First());

But...
Question: how can I select all from each group except the first item?

        var everythingButFirstOfEachGroup = dbContext.Measurements
            .OrderByDescending(m => m.MeasurementId)
            .GroupBy(m => new { m.SomeColumn })
            .Where(g => g.Count() > 1)
            .Select( ...? );

Additional information:
My real goal is to delete all duplicates except the last (in a bulk way, ie: not using an in-memory foreach), so after the previous query I want to use RemoveRange:

 dbContext.Measurements.RemoveRange(everythingButFirstOfEachGroup);

So, if my question has no sense, this information might be handy.

like image 442
sports Avatar asked Feb 09 '15 19:02

sports


1 Answers

Use Skip(1) to skip the first record and select the rest.

Something like:

var firstOfEachGroup = dbContext.Measurements
                    .OrderByDescending(m => m.MeasurementId)
                    .GroupBy(m => new { m.SomeColumn })
                    .Where(g => g.Count() > 1)
                    .SelectMany(g => g.OrderByDescending(r => r.SomeColumn).Skip(1));

See: Enumerable.Skip

If you do not need a flattened collection then replace SelectMany with Select in code snippet.

like image 108
Habib Avatar answered Sep 20 '22 20:09

Habib