【问题标题】:Entity Framework Call Oracle Stored Procedure with Output Parameters using Generic Repository Pattern使用通用存储库模式使用输出参数的实体框架调用 Oracle 存储过程
【发布时间】:2023-04-08 12:36:01
【问题描述】:

我想调用一个简单的存储过程,它有 2 个输出参数,一个 int 和一个字符串。我想使用我的通用存储库模式来获取数据。

这里是 Oracle 存储过程:

create or replace procedure dummy_proc (
    dummy1 in number,
    dummy2 in varchar2,
    dummy3 out number,
    dummy4 out varchar2)
is
begin
    dummy3 := 2500 + dummy1;
    dummy4 := 'Sample text! -> ' || dummy2;
end dummy_proc;

我的通用存储库方法:

public DbRawSqlQuery<T> SQLQuery<T>(string sql, params object[] parameters)
{
  return Context.Database.SqlQuery<T>(sql, parameters);
}

我创建了一个简单的类来保存 2 个输出参数值:

public class Test 
{
  public int dummy1 { get; set; }
  public string dummy2 { get; set; }
}

这是我将用来调用存储库方法的管理器类:

var dummy1 = new OracleParameter("dummy1", OracleDbType.Int32,50, ParameterDirection.Input) { Value = id };
dummy1.Size = 50;

var dummy2 = new OracleParameter("dummy2", OracleDbType.Varchar2,200, ParameterDirection.Input) { Value = model };
dummy2.Size = 200;

var dummy3 = new OracleParameter("dummy3", OracleDbType.Int32,50, ParameterDirection.Output) ;
dummy3.Size = 50;

var dummy4 = new OracleParameter("dummy4", OracleDbType.Varchar2, 200, ParameterDirection.Output) ;
dummy4.Size = 200;

object[] parameters = new object[] { dummy1,dummy2,dummy3,dummy4 };

var test = _repository.SQLQuery<Test>("BEGIN dummy_proc(:dummy1, :dummy2, :dummy3, :dummy4); END;", parameters);

var param3 = dummy3.Value;
var param4 = dummy4.Value;

这段代码似乎正确调用了存储过程,但我的输出参数始终为空。我搜索了几篇文章,但没有一篇使用与我发现的相同的模式。

【问题讨论】:

    标签: oracle entity-framework stored-procedures model-view-controller repository-pattern


    【解决方案1】:

    尝试使用ExecuteSqlCommand 而不是SqlQuery。因为在Oracle存储过程中使用SqlQuery时会出现很多问题。

    更新 1 我发现从 Oracle 返回的输出结果存储在为 OracleParamter 创建的同一变量中。

    【讨论】:

      【解决方案2】:

      我最终更改了存储库方法并使用 ExecuteSqlCommand 而不是 SqlQuery,这现在返回了正确的输出。在我的例子中,我的输出参数只是返回字符串信息,所以我只是连接结果并返回一个 JsonResultMessage。

       public JsonResultMessage ExecuteOracleStoredProcedure(string query, params object[] parameters)
          {
              var result = new JsonResultMessage
              {
                  Success = true,
                  Message = "Successfully executed procedure."
              };
              try
              {
                  var results = _context.Database.ExecuteSqlCommand(query, parameters);
                  var output = new OracleParameter("p_message", OracleDbType.Varchar2, ParameterDirection.Output) { Size = 999000 };
                  foreach (OracleParameter parameter in parameters)
                  {
                      if (parameter.Direction.Equals(ParameterDirection.Output))
                      {
                          result.Message = parameter.Value.ToString();
                      }
                  }
              }
              catch (Exception ex)
              {
                  result.Success = false;
                  result.Message = "Error executing procedure: ." + ex;
              }
              return result;
          }
      

      JsonResultMessage 是我的结果的简单容器:

       public class JsonResultMessage
      {
          public bool Success { get; set; }
          public string Message { get; set; }
      }
      

      当我调用这个方法时,我使用以下语法:

      resultMessage = _repository.ExecuteOracleStoredProcedure("begin IMACMPS1.com_check_end_item(:param1, :param2, :param3);end;",
              new OracleParameter("p_to_site", OracleDbType.Varchar2, ParameterDirection.Input) { Value = siteCode, Size = 50 },
              new OracleParameter("p_part_no ", OracleDbType.Varchar2, ParameterDirection.Input) { Value = partNo, Size = 35 }
            );
      

      其中 check_end_item 是我的过程的名称。

      【讨论】:

        猜你喜欢
        • 2016-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-30
        相关资源
        最近更新 更多