使用Dapper将C#bool作为参数传递给Oracle

时间:2017-02-21 11:20:04

标签: c# oracle dapper

我正在尝试使用Dapper将bool作为参数传递给Oracle,转换为数据库上的1/0字段,如下所示:

public class Customer
{
    public bool Active { get; set; }
}
static void InsertCustomer()
{
    var customer = connect.QueryFirst<Customer>("select 1 active from dual"); // this works
    connect.Execute("insert into customers(active) values(:active)", customer); // this doesn't
}

但这引发了一个例外:

  

System.ArgumentException:'值不在预期范围内   范围'。

我知道我可以创建另一个属性public int ActiveInt => Active ? 1 : 2;,但我希望尽可能保持我的POCO类的清洁,特别是因为Dapper需要公开属性才能将它们用作参数。

我尝试创建bool类型处理程序,但它仅适用于查询列,而不适用于参数:https://github.com/StackExchange/Dapper/issues/303

我还需要将整个对象作为参数传递,因此无法在传递参数时进行转换。

有办法吗?

3 个答案:

答案 0 :(得分:0)

我没有使用Oracle数据库,但是,通过我在网上看到的内容以及我对dapper的了解,您可以尝试将对象转换为dapper动态参数对象并插入:oracle需要的内容每个参数名称的前面。你可以使用我放在一起的扩展方法来做到这一点:

public static class ParameterExtensions
  {
    /// <summary>
    /// Extension method that converts any single dimensional object into Dapper's Dynamic Parameters
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="incoming"></param>
    /// <param name="allowNulls">Provide true to allow nulls to be mapped</param>
    /// <returns></returns>
    public static DynamicParameters ConvertToDynamicParameters<T>(this T incoming, bool allowNulls = false)
    {
      DynamicParameters dynamicParameters = new DynamicParameters();
      foreach (PropertyInfo property in incoming.GetType().GetProperties())
      {
        object value = GetPropValue(incoming, property.Name);
        if (value != null || allowNulls) dynamicParameters.Add($":{property.Name}", value);
      }
      return dynamicParameters;
    }

    private static object GetPropValue(object src, string propName)
    {
      return src.GetType().GetProperty(propName)?.GetValue(src, null);
    }
  }

这是您的实施将改变为:

public class Customer
{
  public bool Active { get; set; }
}
static void InsertCustomer()
{
  var customer = connect.QueryFirst<Customer>("select 1 active from dual"); // this works
  connect.Execute(@"insert into customers(active) values(:active)", customer.ConvertToDynamicParameters()); // this doesn't
}

如果这对你有用,请告诉我。

**注意:您需要在查询和对象中使参数大小写匹配。例如,在您的Customer对象上,您有Customer.Active,此名称必须匹配:active。

答案 1 :(得分:0)

我使用Dapper.SqlMapper.AddTypeMap(Type,DbType)方法。

Future<Null> _selectDate(BuildContext context) async {
  final DateTime picked = await showDatePicker(
    context: context,
    initialDate: _profile?.dob ?? DateTime(2000),
    firstDate: DateTime(1950),
    lastDate: DateTime.now(),
  );
  if (picked != null && picked != _profile?.dob) {
    _formKey.currentState.save();
    _profile?.dob = picked;
    _bloc.dispatch(UpdateEvent(_profile));
  }
}

答案 2 :(得分:0)

如果我们谈论使用Dapper连接到Oracle DB的.NET Core。 我将此与程序一起使用,并且可以正常工作。 Nuget安装Dapper.Oracle。

示例:

在您的C#模型中:

public bool someBoolValue { get; set; }

在您的C#存储库中:

using Dapper;
using Dapper.Oracle;

//in your method
var parameters = new OracleDynamicParameters();
parameters.Add("SOMESQLVARIABLE", yourModel.someBoolValue, OracleMappingType.Int32, ParameterDirection.Input);
parameters.Add("OUT_REFCURSOR", dbType: OracleMappingType.RefCursor, direction: ParameterDirection.Output);
var result = await _dbConnection.ExecuteAsync("my_proc",
                                              parameters,
                                              commandType: CommandType.StoredProcedure);
return result;

DB过程:

PROCEDURE my_proc(
    SOMESQLVARIABLE IN    NUMBER,
    out_refcursor   OUT   SYS_REFCURSOR
)AS
BEGIN
    OPEN out_refcursor FOR SELECT
                               some_column
                           FROM
                               my_table
                           WHERE 
                               my_col = SOMESQLVARIABLE; -- my_col is NUMBER(1,0)

END my_proc;