Usage of stored functions in entity framework
Asked Answered
M

1

6

I have an old Oracle DB which I'm trying to use within EntityFramework 4.1 application.
I've read about the big limitation that oracle has with EF- you can't call Oracle stored Function with EF unless you create a wrapping Procedure.

I got thousands of stored functions in my DB, is there any other way to solve it?
Like using raw Context.SqlQuery()?

So far I couldn't find a solution for it...


Oracle docs:

Oracle developers can leverage PL/SQL stored procedures, with limitations, within the entity framework via Entity Framework Function Imports (used to call the procedures explicitly) and stored procedure mappings (which are automatically called for entity Insert, Update, and Delete operations).

Only Oracle stored procedures can be called by Entity Framework, not stored functions. (Oracle stored functions can be used if they are wrapped inside of a stored procedure that uses an OUT parameter for the stored function return value.)

Mcdougall answered 9/10, 2012 at 11:32 Comment(0)
W
6

If you are working with Entity Framework 4.1 Code First, you can try using the Database.SqlQuery Method . For example, for this function

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

you can use this code:

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

}

EDITED:

Please note this solution for dotConnect for Oracle (maybe it will be useful for implementing a similar solution for ODP.NET)

For this function:

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;

You can use the following code:

   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);
      }

EDITED 2

or use this code:

     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);
 } 
Worked answered 10/10, 2012 at 11:42 Comment(6)
+1 Thanks, but it won't work if the Function has an OUT parameter. :(Mcdougall
Please note, that the answer has been modified once againWorked
Where is the namespace Devart.Data.Oracle located?Mcdougall
As I mentioned above, you can use Devart.Data.Oracle namespace only if you are using dotConnect for Oracle provider.Worked
How can we call oracle package with Entity Framework 6 and Devart.Data.Oracle provider?Tetrabrach
Amir, take a look at this link #21966105Worked

© 2022 - 2024 — McMap. All rights reserved.