如何将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
相关产品推荐
相关产品推荐

