2013-07-24 42 views
6

Sto usando dapper per fare un accesso a Oracle. Ho uno scenario in cui devo avere un parametro di output con un tipo di OracleDbType.Clob. Poiché sto utilizzando dapper e quindi utilizzo l'enumerazione DbType di base, sto utilizzando l'enumerazione DbType.Object come suggerito qui http://docs.oracle.com/html/B14164_01/featOraCommand.htm per sostituire OracleDbType.Clob.Dapper e Oracle Clob tipo

Tuttavia, questo imposta il parametro di comando (in profondità nel dapper) come DbType object e oracle type Blob (come provider DbConnection un concreto OracleParameter). Il problema con questo proc Oracle funziona solo se questo parametro è di tipo Clob not Blob.

Il puro codice ADO funziona come un fascino (utilizzando OracleParameter e OracleConnection, ecc.) Ma non sembra esserci alcun modo per impostare il tipo concreto o l'hook in questo processo di creazione DbParameter in dapper per modificare questo OracleType sul CommandParameter restituito?

Questo funziona:

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

Questo fallisce:

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

Delle idee ??

Grazie,

Jon

risposta

3

so che lei ha chiesto questo molto tempo fa. Tuttavia ho riscontrato lo stesso problema con un tipo di database diverso.

Fondamentalmente si è verificato uno dei problemi con Dapper. È un micro-ormo, questo è un po 'supponente su come le cose dovrebbero funzionare. Sembra che sia stato scritto principalmente con MS SQL Server, anche se afferma che funziona con qualsiasi tipo di database. Che per la maggior parte è vero, tuttavia quando inizi a ottenere più tipi di dati esoterici come Clob, Blob, Geospatial, ecc., Le cose cominciano a crollare come hai visto.

L'unico modo per aggirare questo sarebbe creare un parametro Query personalizzato. È possibile guardare il sorgente ICustomQueryParameter per un esempio qui: https://github.com/SamSaffron/dapper-dot-net/blob/master/Dapper%20NET40/SqlMapper.cs

scendere a questa linea:

sealed partial class DbString : Dapper.SqlMapper.ICustomQueryParameter 

si sarebbe fondamentalmente scrivere il proprio che utilizza OracleDbType.Clob e quindi utilizzarlo in questo modo:

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

ho trovato questo vijaysg/OracleDynamicParameters.cs

Si crea OracleDynamicParameters classe im interfaccia di pasticche IDynamicParameters.

Here è come usarlo

Esempio:

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

e come chiamare con dapper

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

Per il tipo Clob, basta specificare OracleDbType.Clob quando si aggiunge il parametro.

+0

Sembra fantastico! Bello. –

+0

@MarcGravell quando si sceglie di creare/utilizzare un'implementazione IDynamicParameters personalizzata su ICustomQueryParameter? – Damian

+0

@Damian esattamente uno contro 0-a-molti, in pratica –