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

如何将现有T-SQL代码转换为C# LINQ查询(无外键表关联)

将T-SQL汇总查询转换为.NET Core LINQ查询

原T-SQL代码

SELECT p1.PatientId, 
SUM(p1.TotalAmount) as TotalTreatmentAmount, 
SUM(p1.Discount) As TotalTreatmentDiscount,
SUM(p1.Payable) as TotalTreatmentPayable,
SUM(p1.Balance) as TotalTreatmentBalancce,
p2.TotalTreatmentPaidAmount
FROM PatientPayments as p1
join (SELECT p2.PatientId, SUM(p2.PaidAmount) as TotalTreatmentPaidAmount
FROM PatientPaymentHistories p2
where p2.PaymentType != 'Refund' 
group by p2.PatientId) as p2 
ON p2.PatientId = p1.PatientId
group by p1.PatientId, p2.TotalTreatmentPaidAmount

现有代码的问题

你的LINQ代码直接关联两张原始表,没有先对PatientPaymentHistories做过滤退款类型+分组求和,也没有对PatientPayments做分组汇总,最终导出的是明细数据而非T-SQL对应的汇总结果,这是代码不符合预期的核心原因。

正确的LINQ实现(查询语法)

public IActionResult ExportPatientPaymentDataToExcel()
{
    // 先处理PatientPaymentHistories的子查询:过滤退款+按PatientId分组求和
    var paymentHistorySummary = 
        from p2 in _context.PatientPaymentHistories
        where p2.PaymentType != "Refund"
        group p2 by p2.PatientId into g
        select new 
        {
            PatientId = g.Key,
            TotalTreatmentPaidAmount = g.Sum(x => x.PaidAmount)
        };

    // 关联PatientPayments的分组结果和上面的汇总数据
    var patientPaymentSummary =
        from p1 in _context.PatientPayments
        group p1 by p1.PatientId into g
        join ph in paymentHistorySummary on g.Key equals ph.PatientId
        select new 
        {
            PatientId = g.Key,
            TotalTreatmentAmount = g.Sum(x => x.TotalAmount),
            TotalTreatmentDiscount = g.Sum(x => x.Discount),
            TotalTreatmentPayable = g.Sum(x => x.Payable),
            TotalTreatmentBalance = g.Sum(x => x.Balance),
            ph.TotalTreatmentPaidAmount
        };

    // 构建DataTable
    DataTable PatientPaymentTable = new DataTable("PatientPayment");
    PatientPaymentTable.Columns.AddRange(new DataColumn[6]
    {
          new DataColumn("Patient ID"),
          new DataColumn("Total Amount"),
          new DataColumn("Total Discount"),
          new DataColumn("Total Payable"),
          new DataColumn("Total Balance"),
          new DataColumn("Total Paid"),
    });

    // 填充汇总数据到DataTable
    foreach (var summary in patientPaymentSummary)
    {
        PatientPaymentTable.Rows.Add(
            summary.PatientId,
            summary.TotalTreatmentAmount,
            summary.TotalTreatmentDiscount,
            summary.TotalTreatmentPayable,
            summary.TotalTreatmentBalance,
            summary.TotalTreatmentPaidAmount
        );
    }

    // 导出Excel逻辑保持不变
    using (XLWorkbook wb = new XLWorkbook())
    {
        wb.Worksheets.Add(PatientPaymentTable);
        using (MemoryStream stream = new MemoryStream())
        {
            wb.SaveAs(stream);
            return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"{GetLocalDateTime().Date.ToShortDateString()} PatientPayment_Data.xlsx");
        }
    }
}

关键说明

  • 先对PatientPaymentHistories执行过滤和分组求和,得到每个患者的非退款支付总额,和T-SQL的子查询逻辑完全对应。
  • 再对PatientPayments按PatientId分组,计算各项汇总值,然后和上面的支付历史汇总数据关联。
  • DataTable新增了Total Balance列,对应T-SQL中的TotalTreatmentBalancce(原T-SQL拼写有误,代码中修正为TotalTreatmentBalance)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:25:17