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

如何将SQL查询转为带参存储过程并在C# EF中调用获取结果

解决方案:从存储过程生成报表并在EF中调用

我帮你一步步解决这两个问题,先搞定存储过程的创建,再处理EF的调用逻辑。

1. 将SQL查询转换为带参数的存储过程

首先,我们把你提供的SQL改造成支持日期参数的存储过程,同时给返回的CASE表达式列起一个明确的别名,方便后续C#代码映射:

CREATE PROCEDURE dbo.Report
    @StartDate DATETIME,
    @EndDate DATETIME
AS
BEGIN
    SET NOCOUNT ON; -- 减少不必要的返回信息,提升性能

    SELECT 
        CAST(date_rec_slash AS DATETIME) AS DateRecSlash,
        COUNT(code_marz) AS Total,
        CASE 
            WHEN code_marz = 1 THEN 'a' 
            WHEN code_marz = 2 THEN 'b' 
            WHEN code_marz = 3 THEN 'c' 
            WHEN code_marz = 4 THEN 'd' 
            WHEN code_marz = 5 THEN 'e' 
        END AS MarzName
    FROM dbo.tbl_bar 
    WHERE CAST(date_rec_slash AS DATETIME) BETWEEN @StartDate AND @EndDate
    GROUP BY CAST(date_rec_slash AS DATETIME), code_marz 
    ORDER BY CAST(date_rec_slash AS DATETIME) ASC;
END

关键说明:

  • 定义了两个DATETIME类型的参数@StartDate和@EndDate,替换了原来的硬编码日期范围
  • 给每个返回列指定了别名(DateRecSlash、Total、MarzName),确保C#端能正确映射
  • 添加了SET NOCOUNT ON;,避免存储过程返回额外的行数统计信息,提升调用效率

2. 在Entity Framework中调用存储过程并获取结果

你原来的代码直接用tbl_bar实体接收结果是行不通的,因为存储过程返回的是聚合后的统计数据,和tbl_bar表的字段结构不匹配。我们需要先创建一个DTO(数据传输对象)类来匹配存储过程的返回结构:

步骤1:创建ReportResult DTO类

public class ReportResult
{
    // 注意属性名要和存储过程返回的列名完全匹配(大小写不敏感,但建议保持一致)
    public DateTime DateRecSlash { get; set; }
    public int Total { get; set; }
    public string MarzName { get; set; }
}

步骤2:调用存储过程并传递参数

使用EF的Database.SqlQuery<T>方法来执行存储过程,同时通过参数传递日期范围(注意要避免SQL注入,所以不要直接拼接字符串):

方式一:使用SqlParameter对象(推荐,更清晰)

// 假设你的DbContext实例是db
var startDate = new DateTime(2017, 12, 1);
var endDate = new DateTime(2017, 12, 31);

// 定义参数
var parameters = new[]
{
    new SqlParameter("@StartDate", startDate),
    new SqlParameter("@EndDate", endDate)
};

// 执行存储过程并获取结果
var spResults = db.Database.SqlQuery<ReportResult>("EXEC dbo.Report @StartDate, @EndDate", parameters).ToList();

方式二:直接传递参数值(简洁写法)

var startDate = new DateTime(2017, 12, 1);
var endDate = new DateTime(2017, 12, 31);

var spResults = db.Database.SqlQuery<ReportResult>(
    "EXEC dbo.Report @StartDate = @p0, @EndDate = @p1",
    startDate,
    endDate
).ToList();

关键说明:

  • 必须使用和存储过程返回列匹配的DTO类,EF才能自动映射结果
  • 一定要通过参数传递日期值,不要直接拼接SQL字符串,防止SQL注入攻击
  • 调用时最好加上存储过程的架构名(dbo.Report),避免因架构问题找不到存储过程

最后,你就可以把spResults中的数据绑定到前端表格上展示了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:48:39