6

アプリケーション内で使用しようとしている古いOracleDB がありEntityFramework 4.1ます。
オラクルがEFで持っている大きな制限について読んだことがあります-ラップするプロシージャを作成しない限り、EFでOracleストアド関数を呼び出すことはできません。

DB に何千ものストアド関数がありますが、それを解決する他の方法はありますか?
raw を使用するのが好きContext.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 に答える