LINQ to Entities - 在分组数据中创建中值

Posted

技术标签:

【中文标题】LINQ to Entities - 在分组数据中创建中值【英文标题】:LINQ to Entities - create median value in grouped data 【发布时间】:2022-01-07 06:40:40 【问题描述】:

我有一个 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];


后来在上面提到的sn -p中添加如下:

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

用于跳过带有 null 的 businessEmployeeCount

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();

【讨论】:

我收到此消息:CS1061 'IEnumerable' 不包含定义,并且没有可访问的扩展方法 'Median' 接受类型为 'IEnumerable' 的第一个参数找到(您是否缺少 using 指令或程序集引用?) 你想把 null 当作 0 吗?还是想在尝试计算中位数时忽略它们? 我想忽略它们。就像在行中跳过 NULL。另外,如何用this关键字构造这个扩展方法? 对于忽略空值,您可以添加另一个 where 子句businessEmployeeMedian = g.Where(x =&gt; x.businessEmployeeCount.HasValue).Select(x =&gt; (int)x.businessEmployeeCount).Median() @MunirHadrovic 我没明白你在问什么。 “如何用这个关键字构造这个扩展方法?” reference for extension methods

以上是关于LINQ to Entities - 在分组数据中创建中值的主要内容,如果未能解决你的问题,请参考以下文章

LinQ to Entities,Max Date字段,按什么分组

在 LINQ to Entities 中使用交叉应用取消透视数据

在LINQ to Entities查询中调用自定义标量数据库函数?

Linq to Entities - 3 层架构

查询 LINQ to Entities 中联系字段的属性

在实体框架和 Linq to Entities 中使用规范模式和表达式