C# 使用Dapper将C bool作为参数传递给Oracle
我试图使用Dapper将bool作为参数传递给Oracle,将其转换为数据库上的1/0字段,如下所示:C# 使用Dapper将C bool作为参数传递给Oracle,c#,oracle,dapper,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 co
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使用它们作为参数
我尝试创建布尔类型处理程序,但它仅适用于查询列,不适用于参数:
我还需要将整个对象作为参数传递,因此在传递参数时无法进行转换
有什么方法可以做到这一点吗?我没有Oracle DB可供使用,但是,根据我在网上看到的内容以及我对dapper的了解,您可以尝试将您的对象转换为dapper dynamic parameters对象,并在每个参数名称的前面插入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。我使用Dapper.SqlMapper.AddTypeMapType,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();
}
}
如果我们谈论.NET核心使用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;
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;