Linq to dataset выбирает строку на основе максимального значения столбца - PullRequest
1 голос
/ 19 августа 2010

У меня есть таблица набора данных, я хочу сгруппировать ее по столбцу MOID, а затем в этой группе я хочу выбрать строку с максимальным значением столбца radi.

Кто-нибудь может показать мне, как это сделать через LINQ для набора данных?

Ответы [ 3 ]

6 голосов
/ 19 августа 2010

Хотя решение, опубликованное Барри, должно работать (с несколькими исправлениями), оно является неоптимальным: вам не нужно сортировать коллекцию, чтобы найти элемент с максимальным значением поля.Я написал метод расширения WithMax, который возвращает элемент с максимальным значением указанной функции:

    public static T WithMax<T, TValue>(this IEnumerable<T> source, Func<T, TValue> selector)
    {
        var max = default(TValue);
        var withMax = default(T);
        bool first = true;
        var comparer = Comparer<TValue>.Default;
        foreach (var item in source)
        {
            var value = selector(item);
            int compare = comparer.Compare(value, max);

            if (compare > 0 || first)
            {
                max = value;
                withMax = item;
            }
            first = false;
        }
        return withMax;
    }

Он повторяет коллекцию только один раз, что намного быстрее, чем сортировка, чтобы получить первыйitem.

Вы можете использовать его следующим образом

var query =
    from row in table.AsEnumerable()
    group row by row.Field<int>("MOID") into g
    select g.WithMax(r => r.Field<int>("radi"));
2 голосов
/ 19 августа 2010

Это не проверено, но я думаю, что-то вроде этого должно работать:

        var qry = from m in [YourDataSource]
                      group p by m.MOID into grp
                      select grp.OrderByDescending(a => a.RADI).First();
0 голосов
/ 01 июня 2012

это работает с одним запросом!

public static T WithMax<T, TValue>(this IEnumerable<T> source, Func<T, TValue> keySelector)
{
    return source.OrderByDescending(keySelector).FirstOrDefault();
}
...