You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在ASP.NET Entity Framework Core中使用GroupBy()和Min()的方法

问题1:实现等价于指定SQL的EF查询

原SQL实现的是按WorkingArea分组,获取每个区域的最小佣金。你之前的代码仅赋值了Commission,未包含分组键WorkingArea,且直接实例化Agent实体存在隐患(实体其他属性未赋值,易引发异常)。推荐使用匿名类型或自定义DTO承载结果:

方法1:使用匿名类型

var result = _db.Agents
    .GroupBy(a => a.WorkingArea)
    .Select(g => new 
    {
        WorkingArea = g.Key,
        MinCommission = g.Min(a => a.Commission)
    })
    .ToList();

方法2:使用自定义DTO(便于复用)

先定义DTO类:

public class AgentAreaMinCommissionDto
{
    public string WorkingArea { get; set; }
    public decimal MinCommission { get; set; }
}

再执行查询:

List<AgentAreaMinCommissionDto> result = _db.Agents
    .GroupBy(a => a.WorkingArea)
    .Select(g => new AgentAreaMinCommissionDto
    {
        WorkingArea = g.Key,
        MinCommission = g.Min(a => a.Commission)
    })
    .ToList();

以上代码可生成与原SQL完全一致的结果,包含每个区域对应的最小佣金。


问题2:在结果中添加PhoneNo列(注意原SQL的合法性问题)

你给出的SQL SELECT WorkingArea, MIN(Commission), PhoneNo FROM agents GROUP BY WorkingArea 不符合标准SQL规范:PhoneNo既未出现在GROUP BY子句中,也未被聚合函数包裹,数据库无法确定分组后返回哪一条记录的PhoneNo。

以下针对两种合理需求给出实现方案:

需求A:获取每个区域中佣金最低的代理的PhoneNo

方式1:分组找最小佣金后关联原表

var result = _db.Agents
    .GroupBy(a => a.WorkingArea)
    .Select(g => new 
    {
        WorkingArea = g.Key,
        MinCommission = g.Min(a => a.Commission)
    })
    .Join(_db.Agents,
          g => new { g.WorkingArea, g.MinCommission },
          a => new { a.WorkingArea, a.Commission },
          (g, a) => new 
          {
              g.WorkingArea,
              g.MinCommission,
              a.PhoneNo
          })
    .ToList();

方式2:使用窗口函数(EF Core 3.0+支持)

var result = _db.Agents
    .Select(a => new 
    {
        a.WorkingArea,
        a.Commission,
        a.PhoneNo,
        RowNum = EF.Functions.RowNumber()
            .Over(PartitionBy(a.WorkingArea)
                  .OrderBy(a.Commission))
    })
    .Where(x => x.RowNum == 1)
    .Select(x => new 
    {
        x.WorkingArea,
        MinCommission = x.Commission,
        x.PhoneNo
    })
    .ToList();

需求B:返回分组内任意一条记录的PhoneNo(结果不可控,不推荐)

var result = _db.Agents
    .GroupBy(a => a.WorkingArea)
    .Select(g => new 
    {
        WorkingArea = g.Key,
        MinCommission = g.Min(a => a.Commission),
        PhoneNo = g.FirstOrDefault()?.PhoneNo
    })
    .ToList();

内容的提问来源于stack exchange,提问作者Lakshitha Kanchana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 21:50:52