实体框架使用通用存储库模式使用输出参数调用Oracle存储过程

时间:2017-11-05 01:00:44

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

我想调用一个包含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;

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

2 个答案:

答案 0 :(得分:1)

尝试使用ExecuteSqlCommand代替SqlQuery。因为在将SqlQuery与Oracle存储过程一起使用时会遇到很多问题。

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

答案 1 :(得分:0)

我最终更改了存储库方法,并使用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是我的过程的名称。