2012-10-09 51 views
6

我有一箇舊的Oracle DB,我試圖在EntityFramework 4.1應用程序中使用。
我讀過關於甲骨文與EF有很大的侷限性 - 你不能調用Oracle存儲功能與EF,除非你創建一個包裝程序在實體框架中存儲函數的使用

我在我的數據庫中有數以千計的存儲函數,有沒有其他解決方法?
像使用生的Context.SqlQuery()

到目前爲止,我無法找到它的解決方案......


Oracle docs:

Oracle開發人員可以利用PL/SQL存儲過程,有限制的實體內框架通過實體框架功能導入(用於顯式調用過程)和存儲過程映射(自動爲實體插入,更新和刪除操作調用)。

只有Oracle存儲過程可以通過實體框架調用,而不是存儲的函數。 (如果它們被包裝使用的存儲函數的返回值的OUT參數的存儲過程中可以使用Oracle存儲功能)。

回答

6

如果您正在使用實體框架4.1代碼第一次合作,你可以試試使用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爲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); 
     } 

組織編寫

或使用此代碼:

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

+1謝謝,但它不會工作,如果函數有一個'OUT'參數。 ':(' – gdoron

+0

我已編輯答案 – Devart

+0

請注意,答案已被再次修改 – Devart