如何从Oracle存储过程的SystemRefCursor输出参数取值并赋值给List<Model>
在EF Core中调用Oracle存储过程并读取SystemRefCursor输出参数
1. 匹配实体类与游标返回字段
先定义与存储过程游标返回结构一致的Employee实体类,可通过[Column]特性映射Oracle字段名(Oracle默认标识符为大写):
public class Employee { public int EmpId { get; set; } public string EmpName { get; set; } public int DeptId { get; set; } // 补充其他与游标返回对应的属性 }
2. 手动处理数据库命令读取游标
EF Core的ExecuteRawSql对Oracle游标输出支持有限,建议直接操作底层Oracle连接与命令,步骤如下:
using (var connection = _context.Database.GetDbConnection()) { await connection.OpenAsync(); using (var command = connection.CreateCommand()) { // 指定存储过程名称与类型 command.CommandText = "ProcessEmployeeRecords"; command.CommandType = System.Data.CommandType.StoredProcedure; // 添加输入参数(示例中为DeptId=1,参数名需与存储过程定义一致) var deptParam = command.CreateParameter(); deptParam.ParameterName = "p_DeptId"; deptParam.DbType = System.Data.DbType.Int32; deptParam.Value = 1; command.Parameters.Add(deptParam); // 定义SystemRefCursor输出参数 var cursorParam = command.CreateParameter(); cursorParam.ParameterName = "employeeCursor"; cursorParam.DbType = System.Data.DbType.Object; cursorParam.Direction = System.Data.ParameterDirection.Output; // 显式指定Oracle专属的RefCursor类型 ((Oracle.ManagedDataAccess.Client.OracleParameter)cursorParam).OracleDbType = Oracle.ManagedDataAccess.Client.OracleDbType.RefCursor; command.Parameters.Add(cursorParam); // 执行存储过程(先完成数据更新,再返回游标) await command.ExecuteNonQueryAsync(); // 读取游标数据并映射为List<Employee> var employeeList = new List<Employee>(); using (var reader = ((Oracle.ManagedDataAccess.Client.OracleDataReader)cursorParam.Value)) { while (await reader.ReadAsync()) { var employee = new Employee { EmpId = reader.GetInt32(reader.GetOrdinal("EMPID")), EmpName = reader.GetString(reader.GetOrdinal("EMPNAME")), DeptId = reader.GetInt32(reader.GetOrdinal("DEPTID")) // 其他属性按游标字段依次映射 }; employeeList.Add(employee); } } // employeeList即为游标返回的结果集 } }
关键注意事项
- 需提前安装NuGet包:
Oracle.EntityFrameworkCore和Oracle.ManagedDataAccess.Core。 - 存储过程的参数名(包括输入、输出游标)必须与代码中定义完全匹配,注意Oracle标识符的大小写规则。
- 使用
GetOrdinal通过字段名获取索引,避免硬编码索引导致的结构变更错误。
内容的提问来源于stack exchange,提问作者user23538850
相关产品推荐
相关产品推荐

