Хранение одного ряда практически идентичных строк в дататабле с использованием linq - PullRequest
0 голосов
/ 05 октября 2018

У меня есть таблица данных, где могут быть строки, которые почти идентичны, за исключением значений в одном столбце «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.Я хочу поместить результаты этого запроса обратно в таблицу данных с максимальным FileID, чтобы его можно было использовать в представлении данных моей формы.Как это возможно?

1 Ответ

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

После группировки по соответствующим столбцам необходимо выбрать только строку с максимальным значением 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...