2013-07-24 108 views
6

我使用短小精悍做一些Oracle訪問。我有一個場景,我必須有一個類型爲OracleDbType.Clob的輸出參數。由於我使用的短小精悍,因此使用基地的DbType枚舉我用DbType.Object枚舉這裏建議http://docs.oracle.com/html/B14164_01/featOraCommand.htm以代替OracleDbType.Clob。小巧玲瓏與甲骨文CLOB類型

然而,該設置命令參數(在hardy深處)爲對象的DbType和Oracle類型斑點(視的DbConnection提供商的具體的OracleParameter)。如果這個參數的類型是Clob而不是Blob,那麼這個Oracle proc的問題纔有效。

純ADO代碼就像魅力一樣工作(使用OracleParameter和OracleConnection等),但似乎沒有辦法設置具體類型或鉤子到DapParameter創建過程中,以便在返回的CommandParameter上更改此OracleType?

這工作:

using (OracleConnection conn = new OracleConnection("some connection string")) 
{ 
     conn.Open(); 
     var cmd = new OracleCommand("ProcName", conn); 
     cmd.CommandType = CommandType.StoredProcedure; 
     var paramOne = new OracleParameter("ReturnValue", OracleDbType.Clob, int.MaxValue, null, ParameterDirection.Output); 
     cmd.Parameters.Add(paramOne); 
     cmd.ExecuteNonQuery(); 
     var value1 = paramOne.Value; 
} 

這種失敗:

DynamicParameters dyanmicParameters = new DynamicParameters(); 
dyanmicParameters.Add("ReturnValue", null, DbType.Object, ParameterDirection.Output); 
connection.Execute("ProcName", dyanmicParameters, commandType: CommandType.StoredProcedure); 
var val = dynamicParameters.Get<object>("ReturnValue"); 

任何想法?

感謝,

喬恩

回答

3

我知道你問這個是很久以前。不過,我遇到了與其他數據庫類型相同的問題。

基本上你運行到與小巧玲瓏的問題之一。這是一個微觀的東西,對於事情應該如何運作有些opinion然心動。它似乎主要是用MS SQL Server編寫的,儘管它聲稱它可以與任何數據庫類型一起使用。這在大多數情況下是真實的,但是當你開始接觸更多深奧的數據類型時,例如Clob's,Blob's,Geospatial等,事情就像你看到的那樣開始崩潰。

解決這個問題的唯一方法是創建一個自定義查詢參數。你可以看一下ICustomQueryParameter源這裏一個例子:https://github.com/SamSaffron/dapper-dot-net/blob/master/Dapper%20NET40/SqlMapper.cs

深入到這一行:

sealed partial class DbString : Dapper.SqlMapper.ICustomQueryParameter 

你基本上會寫自己的使用OracleDbType.Clob,然後用它是這樣的:

Query<Thing>("select * from Thing where Name = @Name", new { Name = new OracleClob { Value = "abcde" } }); 
6

我發現這個vijaysg/OracleDynamicParameters.cs

它創建OracleDynamicParameters類IM界面IDynamicParameters

Here是如何使用它

樣品:

PROCEDURE GetUserDetailsForPIDM (i_id IN NUMBER, 
       o_user   OUT SYS_REFCURSOR, 
       o_roles   OUT SYS_REFCURSOR); 

以及如何與短小精悍

public static User GetUserDetailsByID(int ID) { 
    User u = null; 
    using (OracleConnection cnn = new OracleConnection(ConnectionString)) { 
     cnn.Open(); 
     var p = new OracleDynamicParameters(); 
     p.Add("i_id", ID); 
     p.Add("o_user", dbType:OracleDbType.RefCursor, direction: ParameterDirection.Output); 
     p.Add("o_roles", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output); 

     using (var multi = cnn.QueryMultiple("PKG_USERS.GetUserDetailsForID", param: p, commandType: CommandType.StoredProcedure)) { 
      u = multi.Read<User>().Single(); 
      u.Roles = multi.Read<UserRole>.ToList(); 
     } 
    } 
    return u; 
} 

對於CLOB類型調用它,只需指定OracleDbType.Clob添加參數時。

+0

看起來不錯!尼斯。 –

+0

@MarcGravell何時會選擇通過ICustomQueryParameter創建/使用自定義IDynamicParameters實現? – Damian

+0

@Damian正好是一對一對0,基本上 –