Type Dapper & Oracle Clob

ado.net dapper oracle

Question

J'utilise Dapper pour faire un accès à Oracle. J'ai un scénario où je dois avoir un paramètre de sortie avec un type de OracleDbType.Clob. Comme j'utilise dapper et utilise donc l'énumération de base DbType, j'utilise l'énumération DbType.Object comme suggéré ici http://docs.oracle.com/html/B14164_01/featOraCommand.htm pour remplacer OracleDbType.Clob.

Cependant, cela définit le paramètre de commande (en profondeur dans dapper) comme étant un objet DbType et un oracle de type Blob (comme les fournisseurs DbConnection fournissent un OracleParameter concret). Le problème étant que ce proc Oracle ne fonctionne que si ce paramètre est de type Clob not Blob.

Le code ADO pur fonctionne comme un charme (Utiliser OracleParameter et OracleConnection, etc.) mais il ne semble pas y avoir de moyen de définir le type concret ou le hook dans ce processus de création DbParameter pour changer ce OracleType sur le CommandParameter renvoyé?

Cela marche:

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

Cela échoue:

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

Des idées??

Merci,

Jon

Réponse acceptée

Je sais que tu l'as demandé il y a longtemps. Cependant, j'ai rencontré le même problème avec un type de base de données différent.

Fondamentalement, vous rencontrez un des problèmes avec Dapper. C'est un micro-orme, c'est un peu critique sur la façon dont les choses devraient fonctionner. Il semble avoir été écrit principalement avec MS SQL Server à l'esprit, même s'il prétend qu'il fonctionne avec n'importe quel type de base de données. Ce qui pour la plupart est vrai, cependant, lorsque vous commencez à accéder à des types de données plus ésotériques tels que Clob, Blob, Geospatial, etc., les choses commencent à se dégrader comme vous l'avez vu.

La seule solution consiste à créer un paramètre de requête personnalisé. Vous pouvez consulter la source ICustomQueryParameter pour un exemple ici: https://github.com/SamSaffron/dapper-dot-net/blob/master/Dapper%20NET40/SqlMapper.cs

Descendez à cette ligne:

sealed partial class DbString : Dapper.SqlMapper.ICustomQueryParameter

En gros, vous écrivez votre propre version qui utilise OracleDbType.Clob , puis l’utilisez comme ceci:

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

Réponse populaire

J'ai trouvé ce vijaysg / OracleDynamicParameters.cs

Il crée la classe OracleDynamicParameters qui implémente l'interface IDynamicParameters .

Voici comment l'utiliser

Échantillon:

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

et comment l'appeler avec 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;
}

Pour le type Clob, spécifiez simplement OracleDbType.Clob lors de l'ajout d'un paramètre.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi