如何将实现分组统计的SQL语句转换为EF Core可用的LINQ语句
EF Core LINQ 实现方案
第一步:先定义输出DTO(可选,也可直接用匿名类)
因为C#属性名不支持-等特殊字符,你可以自定义属性名后映射到SQL列名,也可以直接使用匿名类接收结果:
public class PartApprovalStatDto { public int PartId { get; set; } public bool R67 { get; set; } public bool R115 { get; set; } public bool LPGD { get; set; } public bool CNGD { get; set; } }
如果需要和原SQL的输出列名完全对齐,可以给属性加[Column]注解:
[Column("R-67")] public bool R67 { get; set; }
第二步:编写LINQ查询
你已经配置了导航属性,不需要手动写关联JOIN,EF Core会自动生成对应左连接逻辑,和你提供的SQL效果完全一致:
// 这里_dbContext是你注入的上下文实例 var result = await _dbContext.ApprovalNumberRecord // 可选:如果需要过滤无效数据可以加条件,比如只保留可见的记录 // .Where(anr => anr.IsVisible) .GroupBy(anr => anr.Part.Id) .Select(g => new PartApprovalStatDto { PartId = g.Key, // Any逻辑等价于原SQL Sum(Case...)>0,返回布尔值,执行效率更高 R67 = g.Any(x => x.Approval.ApprovalName == "R-67"), R115 = g.Any(x => x.Approval.ApprovalName == "R115"), LPGD = g.Any(x => x.Approval.ApprovalName == "LPG-D"), CNGD = g.Any(x => x.Approval.ApprovalName == "CNG-D") }) .ToListAsync();
注意事项
- 如果导航属性可能为空,可以用空条件运算符避免空引用,EF Core会自动解析为SQL的空值判断:
x.Approval?.ApprovalName == "R-67" - 如果你需要保留Part的描述、IsVisible等原内层查询的字段,可以在GroupBy的Key里包含对应字段,或者直接从Part表出发做查询,逻辑完全一致。
内容的提问来源于stack exchange,提问作者Patryk Wiśniewski
相关产品推荐
相关产品推荐

