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

如何将含Group By、Having子句的SQL转换为C# EF6的LINQ语句

实现代码

推荐优先使用提前过滤的写法,性能更优:

// 替换为你的实际入参
int targetRegisteredCustomerId = 目标客户ID;
int targetSiteId = 目标站点ID;

var queryResult = context.WholesaleCredit
    // 提前过滤不符合条件的数据,减少后续分组计算的数据量
    .Where(x => x.ExpirationUTCDateTime > DateTime.Now
             && x.RegisteredCustomerId == targetRegisteredCustomerId
             && x.Site.Id == targetSiteId)
    // 按照两个字段分组,对应SQL的GROUP BY逻辑
    .GroupBy(x => new { x.RegisteredCustomerId, SiteId = x.Site.Id })
    // 执行聚合计算,对应SQL的sum、max逻辑
    .Select(g => new 
    {
        TotalSiteCreditAmount = g.Sum(x => x.RemainingAmount),
        MaxExpiryDate = g.Max(x => x.ExpirationUTCDateTime)
    })
    // 符合条件的分组最多只有1条,取第一条结果即可
    .FirstOrDefault();

说明

  1. 你之前的代码只按RegisteredCustomerId单个字段分组,和原始SQL的双字段分组逻辑不符,需要改为匿名类包含两个分组键即可。
  2. 原始SQL的HAVING过滤条件是分组键的等值匹配,提前放到WHERE中过滤,执行效率远高于分组后再过滤,最终生成的SQL执行结果完全一致。
  3. 如果你需要严格对齐原始SQL的HAVING写法,可以使用下面的版本:
int targetRegisteredCustomerId = 目标客户ID;
int targetSiteId = 目标站点ID;

var queryResult = context.WholesaleCredit
    .Where(x => x.ExpirationUTCDateTime > DateTime.Now)
    .GroupBy(x => new { x.RegisteredCustomerId, SiteId = x.Site.Id })
    // 对应原始SQL的HAVING过滤逻辑
    .Where(g => g.Key.RegisteredCustomerId == targetRegisteredCustomerId && g.Key.SiteId == targetSiteId)
    .Select(g => new 
    {
        TotalSiteCreditAmount = g.Sum(x => x.RemainingAmount),
        MaxExpiryDate = g.Max(x => x.ExpirationUTCDateTime)
    })
    .FirstOrDefault();
  1. 如果你的WholesaleCredits实体类后续补充了显式的SiteId字段,直接替换x.Site.Id为x.SiteId即可,查询性能会更高。
  2. 若没有符合条件的数据,queryResult会返回null,使用前建议做空值判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:15:04