У меня есть таблица данных, где могут быть строки, которые почти идентичны, за исключением значений в одном столбце «FileID». Столбец, который может отличаться, содержит данные Int32, и я хотел бы сохранить только строку, которая имеет максимальное значение этого столбца, когда строки дублируются. Если строки не дублируются, я бы хотел сохранить одну строку.

var Test = dt.AsEnumerable()
                .GroupBy(r => new
                {
                    Tool = r.Field<string>("Tool"),
                    Plate = r.Field<string>("Plate"),
                    Lot = r.Field<string>("Lot"),
                    Time1 = r.Field<DateTime>("Time1"),
                    Tool2 = r.Field<string>("Tool2"),
                    Time2 = r.Field<DateTime>("Time2"),
                    Recipe = r.Field<string>("Recipe"),
                    Row = r.Field<Int16>("Row")
                }).OrderBy(t => t.Max(r => r.Field<Int32>("FileID")));

Кажется, это правильно фильтрует строки, но я теряю столбец FileID. Я хочу вернуть результаты этого запроса в таблицу данных с максимальным идентификатором файла, чтобы его можно было использовать в datagridview моей формы. Как это возможно?

0
ejyoung 5 Окт 2018 в 21:36

1 ответ

Лучший ответ

После группировки по соответствующим столбцам вам нужно выбрать только строку с максимальным значением FileID из каждой группы, а затем вы можете использовать расширение CopyToDataTable:

var ans = dt.AsEnumerable()
            .GroupBy(r => new {
                Tool = r.Field<string>("Tool"),
                Plate = r.Field<string>("Plate"),
                Lot = r.Field<string>("Lot"),
                Time1 = r.Field<DateTime>("Time1"),
                Tool2 = r.Field<string>("Tool2"),
                Time2 = r.Field<DateTime>("Time2"),
                Recipe = r.Field<string>("Recipe"),
                Row = r.Field<Int16>("Row")
            })
            .Select(rg => rg.OrderByDescending(r => r.Field<Int32>("FileID")).First())
            .CopyToDataTable();

Примечание. Учитывая, что вы используете LINQ to Objects, OrderBy / First не самый эффективный способ найти строку с max FileID. Возможно, у вас недостаточно данных, чтобы иметь значение, но вы можете использовать метод расширения, MaxBy, который выполняет один проход по данным и находит соответствующую строку:

public static T MaxBy<T, TKey>(this IEnumerable<T> src, Func<T, TKey> keySelector) => src.Aggregate((a, b) => Comparer<TKey>.Default.Compare(keySelector(a), keySelector(b)) > 0 ? a : b);

var ans = dt.AsEnumerable()
            .GroupBy(r => new {
                Tool = r.Field<string>("Tool"),
                Plate = r.Field<string>("Plate"),
                Lot = r.Field<string>("Lot"),
                Time1 = r.Field<DateTime>("Time1"),
                Tool2 = r.Field<string>("Tool2"),
                Time2 = r.Field<DateTime>("Time2"),
                Recipe = r.Field<string>("Recipe"),
                Row = r.Field<Int16>("Row")
            })
            .Select(rg => rg.MaxBy(r => r.Field<Int32>("FileID")))
            .CopyToDataTable();
1
NetMage 5 Окт 2018 в 19:38