.NET 5 Web API中如何通过EF Core 5执行返回原始JSON的存储过程
.NET 5 + EF Core 5 调用返回原始JSON的SQL Server存储过程方案
问题背景
在SQL Server中创建了直接返回原始JSON格式数据的存储过程,存储过程不返回可映射到实体类/普通对象的结构化结果,尝试调用时在智能提示中找不到检索到的FromSqlRaw方法,需求是执行存储过程后直接将返回的JSON结果存入变量。
找不到FromSqlRaw的核心原因
FromSqlRaw是EF Core针对**已配置映射的实体对应的DbSet<T>**的扩展方法,仅用于返回可映射到实体的结构化查询结果。你的存储过程返回的是原始JSON字符串,没有对应映射实体,自然不会出现该方法的智能提示,也完全不需要使用该方法实现需求。
可直接落地的实现代码
EF Core 5 已经原生支持非实体类型的原始查询,不需要引入额外依赖,选以下任意一种写法即可:
写法1:使用EF Core 5原生
SqlQueryRaw(代码最简洁,推荐)
该方法直接通过Database实例调用,不需要依赖DbSet,会直接读取查询返回的原始值:// 替换成你自己的存储过程名、参数,无参数就去掉参数部分 var jsonResult = await _yourDbContext.Database .SqlQueryRaw<string>( "EXEC YourStoredProcedureName @Param1, @Param2", new SqlParameter("@Param1", param1Value), new SqlParameter("@Param2", param2Value) ) .FirstOrDefaultAsync();说明:SQL Server中通过
SELECT ... FOR JSON PATH/AUTO返回的JSON结果本质是单行单列的nvarchar(max)字符串,FirstOrDefaultAsync()会直接拿到完整的JSON内容,不会出现拆分截断问题。写法2:通过底层ADO.NET接口执行(兼容性最高,适合需要自定义命令逻辑的场景)
直接从EF Core的上下文拿数据库连接执行命令,绕开EF Core的映射逻辑:var dbConnection = _yourDbContext.Database.GetDbConnection(); await dbConnection.OpenAsync(); using var command = dbConnection.CreateCommand(); command.CommandText = "YourStoredProcedureName"; command.CommandType = System.Data.CommandType.StoredProcedure; // 按需添加存储过程参数 // command.Parameters.Add(new SqlParameter("@ParamName", paramValue)); // 执行后拿到第一行第一列的结果,转成字符串就是完整JSON var jsonResult = await command.ExecuteScalarAsync() as string;
避坑提示
- 不要为了用
FromSqlRaw专门创建空实体类做映射,会因为返回内容和实体结构不匹配抛出映射错误,完全多此一举。 - 不要用
ToList()读取FOR JSON返回的结果,SQL Server会把过长的JSON拆成2033字节长度的多行返回,ToList()会拿到多个字符串碎片,必须拼接才能得到完整JSON,用FirstOrDefault()或者ExecuteScalar()不会有这个问题。
内容的提问来源于stack exchange,提问作者Nilesh
相关产品推荐
相关产品推荐

