Получить различие, используя LINQ to Objects - PullRequest
0 голосов
/ 16 октября 2018

Мои данные выглядят следующим образом enter image description here

Итак, я загрузил их в коллекцию, используя объекты anon для обхода создания класса

List<dynamic> myList = new List<dynamic>()
        {
            new {
                WorkOrderID = 40001,
                LastUpdatedAt = DateTime.Parse("2018-10-02"),
                Col3 = "abc",
                Col4 = "xyz"
            },
            new {
                WorkOrderID = 40001,
                LastUpdatedAt = DateTime.Parse("2017-06-01"),
                Col3 = "abc",
                Col4 = "xyz"
            },
            new {
                WorkOrderID = 40002,
                LastUpdatedAt = DateTime.Parse("2018-07-01"),
                Col3 = "abc",
                Col4 = "xyz"
            },
            new {
                WorkOrderID = 40003,
                LastUpdatedAt = DateTime.Parse("2018-09-01"),
                Col3 = "abc",
                Col4 = "xyz"
            },
            new {
                WorkOrderID = 40001,
                LastUpdatedAt = DateTime.Parse("2016-01-01"),
                Col3 = "abc",
                Col4 = "xyz"
            },
            new {
                WorkOrderID = 40002,
                LastUpdatedAt = DateTime.Parse("2016-12-01"),
                Col3 = "abc",
                Col4 = "xyz"
            },
        };

Как использовать Linq-to-Objects для извлечения только DISTINCT WorkOrders, которые были обновлены в последнее время.

Другими словами, я должен в итоге выделить 3 строки, выделенные оранжевым.

var myFilteredList = myList.GroupBy (// ?? Полностью потеряно ... help ...

Ответы [ 3 ]

0 голосов
/ 16 октября 2018

Далее используется перегрузка GroupBy, поэтому выбор элемента можно выполнить в одном вызове и преобразовать их в строго типизированный анонимный объект.

var myFilteredList = myList
    .GroupBy(_ => (int)_.WorkOrderID, (k, g) =>
    {
        var recent = g.OrderByDescending(_ => _.LastUpdatedAt).First();
        return new
        {
            WorkOrderID = k,
            LastUpdatedAt = (DateTime)recent.LastUpdatedAt,
            Col3 = (string)recent.Col3,
            Col4 = (string)recent.Col4
        };
    });

Fiddle

0 голосов
/ 16 октября 2018
List<dynamic> list = myList
               .GroupBy(a => a.WorkOrderID )
               .OrderByDescending(b => b.LastUpdatedAt)
               .Select(g => g.FirstOrDefault())
               .ToList();

foreach (var p in list)
{
    Console.WriteLine(p.WorkOrderID + " : " + p.Col3);
}

Лично динамический не является хорошим выбором.Если у вас есть объект, вы можете реализовать Equals и GetHashCode на объекте.Таким образом, вы можете сделать:

var list = myList.Select(o => new { o.WorkOrderID, ... })
                                       .Distinct();

, что намного чище.

0 голосов
/ 16 октября 2018

Если я не ошибаюсь, вам нужен новейший элемент для каждого рабочего заказа.

var latestWorkOrders = myList
    .GroupBy(w => w.WorkOrderID)
    .Select(g => g.OrderByDescending(w => w.LastUpdatedAt).First());

Группируется по WorkOrderID, и для каждой группировки выбирается самый новый элемент.

...