My aim is to create custom struct that wrapping double and save it to database using Dapper. Unfortunately I've faced a problem I can't fix.
I've created following struct:
public struct MyDouble
{
private readonly double value;
public static implicit operator MyDouble(double val)
{
return new MyDouble(val);
}
public static explicit operator double(MyDouble val)
{
return val.value;
}
public static explicit operator MyDouble(int val)
{
return new MyDouble(val);
}
public MyDouble(double val)
{
this.value = Process(val);
}
public double GetDouble()
{
return this.value;
}
}
and added custom type handler as it described here (https://medium.com/dapper-net/custom-type-handling-4b447b97c620)
public class MyDoubleTypeHandler : SqlMapper.TypeHandler<MyDouble>
{
public override MyDouble Parse(object value)
{
return (MyDouble)value;
}
public override void SetValue(IDbDataParameter parameter, MyDouble value)
{
parameter.DbType = DbType.Double;
parameter.Value = value.GetDouble();
}
}
My custom objects with MyDouble
prop inside:
public class MyObject
{
public MyDouble Prop1 { get; set; }
}
And save method looks like:
public async Task<bool> Save(List<MyObject> data)
{
SqlMapper.ResetTypeHandlers();
SqlMapper.AddTypeHandler(new MyDoubleTypeHandler());
parameters.AddTable("@Data", "dbo.MyObject", data.AsList());
using (var connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
return await connection.ExecuteAsync("name-of-sp", parameters, commandType: CommandType.StoredProcedure);
}
}
As a result I get this error: "System.ArgumentException: The type of column 'Prop1' is not supported. The type is 'MyDouble'".
It seems to be that my custom type handler hasn't been registered despite the fact I do it directly by calling SqlMapper.AddTypeHandler(new MyDoubleTypeHandler());
Could anyone help with that problem?
P.S. I'm using Dapper 1.50.5, Dapper.ParameterExtensions 2018.12.7.1 inside Asp.NET Core app (2.1)
Looking at the tests in the source code it seems you need to use a different overload to set the Type Handler:
https://github.com/StackExchange/Dapper/blob/master/Dapper.Tests/TypeHandlerTests.cs#L101
and also the Type Handler class is slightly different:
https://github.com/StackExchange/Dapper/blob/master/Dapper.Tests/TypeHandlerTests.cs#L116
as the constructor is set to be private in order to make sure the usual methon
SqlMapper.AddTypeHandler<T>(TypeHandler<T>)
won't be used .