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

如何从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:25:05