我正在尝试使用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
我还需要将整个对象作为参数传递,因此无法在传递参数时进行转换。
有办法吗?
答案 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;