如何在Entity Framework Core 7.0中调用返回非表结果集的存储过程
EF Core 7.0 调用无映射结果集的存储过程并映射到自定义类
1. 准备自定义结果类
先定义一个和存储过程返回字段匹配的类,属性名需和存储过程输出列名一致(大小写不敏感,数据库区分大小写场景除外),若列名与属性名不匹配,可通过[Column]特性映射:
public class CustomProcedureResult { public int Id { get; set; } public string ProductName { get; set; } [Column("Total_Sales")] // 映射存储过程返回的Total_Sales列 public decimal TotalSales { get; set; } }
2. 方法一:使用EF Core 7.0新增的SqlQuery(推荐)
EF Core 7.0引入的SqlQuery专门用于处理无实体映射的结果集,无需在DbContext中注册该类:
调用无参数存储过程
using var context = new YourDbContext(); var results = await context.Database.SqlQuery<CustomProcedureResult>( "EXEC GetProductSalesSummary" ).ToListAsync();
调用带参数的存储过程(安全防注入)
方式1:使用SqlParameter
var startDateParam = new SqlParameter("@StartDate", new DateTime(2023, 1, 1)); var categoryParam = new SqlParameter("@Category", "Electronics"); var results = await context.Database.SqlQuery<CustomProcedureResult>( "EXEC GetProductSalesSummary @StartDate, @Category", startDateParam, categoryParam ).ToListAsync();
方式2:使用字符串插值(EF Core自动转为参数化查询)
DateTime startDate = new DateTime(2023, 1, 1); string category = "Electronics"; var results = await context.Database.SqlQuery<CustomProcedureResult>( $"EXEC GetProductSalesSummary {startDate}, {category}" ).ToListAsync();
3. 方法二:使用FromSqlRaw(需临时注册DbSet)
若偏好传统的FromSqlRaw,需在DbContext中添加一个未映射的DbSet:
步骤1:在DbContext中配置未映射的DbSet
public class YourDbContext : DbContext { // 临时DbSet,无需映射到数据库表 public DbSet<CustomProcedureResult> CustomResults { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 标记该类为无主键、无映射表 modelBuilder.Entity<CustomProcedureResult>().HasNoKey().ToView(null); } // 其他DbSet及配置... }
步骤2:调用存储过程
using var context = new YourDbContext(); // 无参数调用 var results = await context.CustomResults.FromSqlRaw("EXEC GetProductSalesSummary").ToListAsync(); // 带参数调用 var statusParam = new SqlParameter("@Status", "InStock"); var filteredResults = await context.CustomResults.FromSqlRaw("EXEC GetProductSalesSummary @Status", statusParam).ToListAsync();
注意事项
- 自定义类的属性类型必须与存储过程返回列的类型兼容,否则会抛出类型转换异常。
- 若存储过程返回多个结果集,需结合
context.Database.ExecuteSqlRaw与DataReader手动处理。 - 所有参数传递必须使用参数化方式,杜绝SQL注入风险。
内容的提问来源于stack exchange,提问作者DevSab
相关产品推荐
相关产品推荐

