ПРИВЯЗКА к объектам — создание среднего значения в сгруппированных данных

#c# #entity-framework #linq #grouping

#c# #entity-framework #linq #группировка

Вопрос:

У меня есть запрос LINQ to Entities для группировки данных и одновременного добавления некоторых агрегатов, и он работает, за исключением вычисления медианного значения. Среднее значение вычисляется по отсортированным столбцам, разделенным на 2 (получаем среднее значение из столбца). Вот мой пример:

 private void button2_Click(object sender, EventArgs e)
    {
        var query = from t in _database.jon_export
                    orderby t.businessEmployeeCount
                    group t by t.county.ToString() into g
                    where g.Count() > 0
                    select new
                    {
                        County = g.Key,
                        CountValue = g.Count(),
                        BusinessEmployeeCount = g.Count(),
                        BusinessEmployeeAverageValue = g.Average(x => x.businessEmployeeCount),
                        //Median value from businessEmployeeCount column
                        BusinessRevenueAverageValue = g.Average(x => x.businessRevenue),  
                        BusinessTurnover=g.Average(x => x.businessTurnover),
                        BooiqEconomicWellBeing=g.Average(x=>x.booiqEconomicWellBeing)
                    };
        this.dataGridView1.DataSource = query.ToList();
    }
 

Ответ №1:

Напишите метод расширения в IEnumerable и вызовите этот метод расширения в коде с правильным свойством.

 public static double Median(this IEnumerable<int> items)
{
    var data = items.OrderBy(n => n).ToArray();
    if (data.Length % 2 == 0)
        return (data[data.Length / 2 - 1]   data[data.Length / 2]) / 2.0;
    return data[data.Length / 2];
}

 

и позже в вышеупомянутом фрагменте добавьте следующее:

 businessEmployeeMedian =  g.Select(x => x.businessEmployeeCount).Median(), 
 

Для пропуска businessEmployeeCount с null

 businessEmployeeMedian = g.Where(x => x.businessEmployeeCount.HasValue).Select(x => (int)x.businessEmployeeCount).Median()
 

Завершите linq в синтаксисе метода

 
            var items = _database.jon_export
            .OrderBy(item => item.businessEmployeeCount)
            .GroupBy(item => item.County)
            .Where(g => g.Any())
            .Select(g => {
                return new
                {
                    County = g.Key,
                    CountValue = g.Count(),
                    BusinessEmployeeCount = g.Count(),
                    BusinessEmployeeAverageValue = g.Average(x => x.businessEmployeeCount),
                    businessEmployeeMedian = g.Where(x => x.businessEmployeeCount.HasValue).Select(x => (int)x.businessEmployeeCount).Median(),
                    BusinessRevenueAverageValue = g.Average(x => x.businessRevenue),
                    BusinessTurnover = g.Average(x => x.businessTurnover),
                    BooiqEconomicWellBeing = g.Average(x => x.booiqEconomicWellBeing)
                };
            }).ToList();

 

Комментарии:

1. Я получил это сообщение: CS1061 ‘IEnumerable<int?>’ не содержит определения и не может быть найден доступный метод расширения ‘Median’, принимающий первый аргумент типа ‘IEnumerable<int?>’ (вам не хватает директивы using или ссылки на сборку?)

2. вы хотите принять null за 0? или вы хотели бы игнорировать их при попытке вычислить медиану?

3. Я бы хотел их игнорировать. Например, пропустить нули в строках. Кроме того, как структурировать этот метод расширения с помощью этого ключевого слова?

4. для игнорирования нулевых значений вы можете добавить другое предложение where businessEmployeeMedian = g.Where(x => x.businessEmployeeCount.HasValue).Select(x => (int)x.businessEmployeeCount).Median()

5. @MunirHadrovic я не понял, о чем ты спрашиваешь. «как структурировать этот метод расширения с помощью этого ключевого слова?» ссылка на методы расширения