7

我正在使用 dapper 进行一些 oracle 访问。我有一个场景,我必须有一个类型为 OracleDbType.Clob 的输出参数。当我使用 dapper 并因此使用基本 DbType 枚举时,我正在使用此处建议的 DbType.Object 枚举http://docs.oracle.com/html/B14164_01/featOraCommand.htm来代替 OracleDbType.Clob。

但是,这会将命令参数(深入 dapper)设置为 DbType 对象和 oracle 类型 Blob(因为 DbConnection 提供了具体的 OracleParameter)。这个 Oracle proc 的问题只有在这个参数的类型是 Clob 而不是 Blob 时才有效。

纯 ADO 代码就像一个魅力(使用 OracleParameter 和 OracleConnection 等),但似乎无法在 dapper 中设置具体类型或挂钩到此 DbParameter 创建过程中以更改返回的 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");

有任何想法吗??

谢谢,

乔恩

4

2 回答 2

7

我找到了这个vijaysg / OracleDynamicParameters.cs

它创建OracleDynamicParameters类实现IDynamicParameters接口。

是如何使用它

样本:

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

以及如何用 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;
}

对于 Clob 类型,只需OracleDbType.Clob在添加参数时指定即可。

于 2014-08-07T06:07:58.333 回答
3

我知道你很久以前就问过这个问题。但是,我在使用不同的数据库类型时遇到了同样的问题。

基本上你遇到了 Dapper 的问题之一。这是一个微观结构,对事情应该如何运作有些固执己见。它似乎主要是考虑到 MS SQL Server 编写的,尽管它声称它适用于任何数据库类型。这在大多数情况下是正确的,但是当您开始使用更深奥的数据类型(例如 Clob、Blob、地理空间等)时,正如您所见,事情开始崩溃。

解决此问题的唯一方法是创建自定义查询参数。您可以在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" } });
于 2014-04-14T20:39:05.750 回答