6

我有一个Oracle试图在EntityFramework 4.1应用程序中使用的旧数据库。
我已经阅读了 oracle 对 EF 的巨大限制-除非您创建包装程序,否则您不能使用 EF 调用 Oracle 存储函数

我的数据库中有数千个存储函数,还有其他方法可以解决吗?
喜欢使用 rawContext.SqlQuery()吗?

到目前为止,我找不到解决方案...


甲骨文文档:

Oracle 开发人员可以通过实体框架函数导入(用于显式调用过程)和存储过程映射(为实体插入、更新和删除操作自动调用)在实体框架内利用 PL/SQL 存储过程,但有限制。

Entity Framework 只能调用 Oracle 存储过程,不能调用存储函数。(如果将 Oracle 存储函数包装在使用 OUT 参数作为存储函数返回值的存储过程中,则可以使用它们。)

4

1 回答 1

6

如果您使用的是 Entity Framework 4.1 Code First,您可以尝试使用Database.SqlQuery Method。例如,对于这个函数

CREATE OR REPLACE FUNCTION USERNAME_CTX.FUNCTION1 (param number)
 RETURN number
AS
BEGIN
 return param + 1;
END;

您可以使用以下代码:

using (var ctx = new Model()) {
   var result =  ctx.Database.SqlQuery<int>("select username_ctx.FUNCTION1(:p0) from dual",1).FirstOrDefault();

}

编辑:

请注意这个针对 dotConnect for Oracle 的解决方案(也许它对于为 ODP.NET 实施类似的解决方案很有用)

对于此功能:

CREATE OR REPLACE FUNCTION USERNAME_CTX.FUNCTION2 (param number, int_param out number, str_param out varchar2)
  RETURN number
AS
BEGIN
   int_param := param + 2;
   str_param := 'value';
   return param + 1;
END;

您可以使用以下代码:

   using (var ctx = new Model()) {
       var firstParam = new Devart.Data.Oracle.OracleParameter("p0", OracleDbType.Number, 1, ParameterDirection.Input);
       var secondParam = new Devart.Data.Oracle.OracleParameter("p1", OracleDbType.Number, ParameterDirection.Output);
       var thirdParam = new Devart.Data.Oracle.OracleParameter("p2", OracleDbType.VarChar, ParameterDirection.Output);
       var cursorParam = new Devart.Data.Oracle.OracleParameter("cursor_param", OracleDbType.Cursor, ParameterDirection.Output);

       var result = ctx.Database.SqlQuery<int>(
        @"declare
             res number;  
        begin
             res := username_ctx.FUNCTION2(:p0, :p1, :p2);
             open :cursor_param for select res from dual;
        end;",  firstParam, secondParam, thirdParam, cursorParam).FirstOrDefault();

       Console.WriteLine("Return value: {0}; int_param: {1}; str_param: '{2}'", result, secondParam.Value, thirdParam.Value);
      }

已编辑 2

或使用此代码:

     using (var ctx = new Model()) {
       var firstParam = new Devart.Data.Oracle.OracleParameter("p0", OracleDbType.Number, 1, ParameterDirection.Input);
       var secondParam = new Devart.Data.Oracle.OracleParameter("p1", OracleDbType.Number, ParameterDirection.Output);
       var thirdParam = new Devart.Data.Oracle.OracleParameter("p2", OracleDbType.VarChar, ParameterDirection.Output);
       var resultParam = new Devart.Data.Oracle.OracleParameter("res", OracleDbType.Number, 1, ParameterDirection.Output);
       ctx.Database.ExecuteSqlCommand(@"begin  :res := username_ctx.FUNCTION2(:p0, :p1, :p2);  end;", firstParam, secondParam, thirdParam, resultParam);
       Console.WriteLine("Return value: {0}; int_param: {1}; str_param: '{2}'", resultParam.Value, secondParam.Value, thirdParam.Value);
 } 
于 2012-10-10T11:42:59.477 回答