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

Entity Framework Core调用返回标量值存储过程的最优解决方案

EF Core 5.0 调用返回标量值存储过程的最优方案

报错原因修复

你遇到的ExecuteSqlCommandAsync不存在的编译错误,是因为EF Core 3.0+版本已将该方法重命名为ExecuteSqlRawAsync,同时需要在SQL语句中给输出参数加上OUTPUT标识,修正后的代码如下:

SqlParameter orderId = new SqlParameter("@orderid",orderId);
SqlParameter customerid = new SqlParameter("@customerid", customerId);
SqlParameter isDelivered = new SqlParameter
{
    ParameterName = "@Value",
    SqlDbType = System.Data.SqlDbType.BigInt,
    Direction = System.Data.ParameterDirection.Output
};

await _dbContext.Database.ExecuteSqlRawAsync("[dbo].[is_delivered] @orderid , @customerid, @Value OUTPUT", orderId , customerid, isDelivered);
var result = Convert.ToInt64(isDelivered.Value);

最优通用方案(无实体,不受Scaffold影响)

推荐直接调用DbContext底层的ADO.NET连接执行标量查询,不需要定义任何额外实体,也不会被dbScaffold --force操作覆盖,兼容所有返回标量的存储过程场景:

await using var cmd = _dbContext.Database.GetDbConnection().CreateCommand();
// 存储过程名
cmd.CommandText = "dbo.is_delivered";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
// 传入参数
cmd.Parameters.Add(new SqlParameter("@orderid", orderId));
cmd.Parameters.Add(new SqlParameter("@customerid", customerId));

// 打开连接执行查询
await _dbContext.Database.OpenConnectionAsync();
var result = Convert.ToInt64(await cmd.ExecuteScalarAsync());

该方案优势:

  • 无额外实体定义成本,不需要在DbContext中注册任何模型
  • 完全不受Database First模式下Scaffold操作的影响
  • 执行效率更高,省去了实体映射的开销

可选:保留无键实体的兼容方案

如果你希望继续使用原来的ScalarBool无键实体方案,可以把实体配置写到单独的DbContext分部类中,避免被自动生成的代码覆盖:

  1. 新建和自动生成的DbContext同名的分部类文件,比如MyDbContext.partial.cs
  2. 在文件中实现OnModelCreatingPartial方法,写入自定义配置:
public partial class MyDbContext
{
    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ScalarBool>().HasNoKey();
    }
}

执行Scaffold操作时只会覆盖自动生成的类文件,不会修改自定义的分部类内容,ScalarBool的配置会永久保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:36:03