【问题标题】:Pass C# bool as parameter to Oracle using Dapper使用 Dapper 将 C# bool 作为参数传递给 Oracle
【发布时间】:2017-02-21 11:20:03
【问题描述】:

我正在尝试使用 Dapper 将布尔值作为参数传递给 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 =&gt; Active ? 1 : 2;,但我希望我的 POCO 类尽可能干净,特别是因为属性需要公开,以便 Dapper 将它们用作参数。

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

我还需要将整个对象作为参数传递,所以在传递参数时转换是不可能的。

有没有办法做到这一点?

【问题讨论】:

    标签: c# oracle dapper


    【解决方案1】:

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

    public class Customer
    {
        public bool Active { get; set; }
    }
    
    class Program : IDisposable
    {
        private readonly DbConnection _connection;
    
        public Program()
        {
            _connection = DbOpen();
        }
    
        static void Main(string[] args)
        {
            SqlMapper.AddTypeMap(typeof(bool), DbType.Int32);
    
            using (var program = new Program())
            {
                program.Run();
            }
        }
    
        private void Run()
        {
            _connection.Execute($"INSERT INTO customers ( active ) VALUES (:Activate)", new { Activate = true });
            _connection.Execute($"INSERT INTO customers ( active ) VALUES (:Activate)", new { Activate = false });
    
            var customers = new List<Customer>()
            {
                new Customer() {Active = true},
                new Customer() {Active = false}
            };
            _connection.Execute($"INSERT INTO customers ( active ) VALUES (:{nameof(Customer.Active)})", customers);
    
            var results = _connection.Query<Customer>("SELECT * FROM customers");
            foreach (var customer results)
            {
                Console.WriteLine($"{nameof(Customer.Active)} is {customer.Active}");
            }
        }
    
        private static DbConnection DbOpen()
        {
            var connectionSetting = ConfigurationManager.ConnectionStrings["oracle"];
            var dbFactory = DbProviderFactories.GetFactory(connectionSetting.ProviderName);
            var conn = dbFactory.CreateConnection();
            conn.ConnectionString = connectionSetting.ConnectionString;
            conn.Open();
            return conn;
        }
    
        public void Dispose()
        {
            _connection?.Dispose();
        }
    }
    

    【讨论】:

      【解决方案2】:

      我没有可使用的 Oracle DB,但是,根据我在网上看到的以及我对 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.Active,此名称必须匹配 :active。

      【讨论】:

        【解决方案3】:

        如果我们谈论 .NET Core 使用 Dapper 连接到 Oracle DB。 我将它与程序一起使用,它可以工作。 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;
        

        数据库过程:

        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;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-09
          相关资源
          最近更新 更多