Open joshbartley opened 1 year ago
Hi,
Yes, it seems to be a compatibility issue between ClickHouse.Client
's type system and the way Dapper performs conversions
As an interim solution, does using a handler like:
private class ClickHouseNullableDecimalHandler : SqlMapper.TypeHandler<decimal?>
{
public override void SetValue(IDbDataParameter parameter, decimal? value) => parameter.Value = value.ToString(CultureInfo.InvariantCulture);
public override decimal? Parse(object value) => value switch
{
DBNull => null,
null => null,
ClickHouseDecimal chd => chd.ToDecimal(CultureInfo.InvariantCulture),
IConvertible ic => Convert.ToDecimal(ic),
_ => throw new ArgumentException(null, nameof(value))
};
}
SqlMapper.AddTypeHandler(new ClickHouseNullableDecimalHandler ());
improve the situation for you?
I think that could work. For now we went to manual mapping because Dapper doesn't have a per query type handler system and we have way to many places do double check for that instead of writing out like 15 lines of mapping code. This also allowed us access to the QueryStats.
What I'm suggesting is to add this handler to your code
private class ClickHouseNullableDecimalHandler : SqlMapper.TypeHandler<decimal?>
{
public override void SetValue(IDbDataParameter parameter, decimal? value) => parameter.Value = value.ToString(CultureInfo.InvariantCulture);
public override decimal? Parse(object value) => value switch
{
DBNull => null,
null => null,
ClickHouseDecimal chd => chd.ToDecimal(CultureInfo.InvariantCulture),
IConvertible ic => Convert.ToDecimal(ic),
_ => throw new ArgumentException(null, nameof(value))
};
}
SqlMapper.AddTypeHandler(new ClickHouseNullableDecimalHandler ());
This is a static operation and should not require using manual mapping. As another workaround, you can try using UseCustomDecimals=false
in connection string to revert to .NET decimals
I understand that, this is an existing code base connected to more than Clickhouse with Dapper and taking over the default mapping for all Dapper queries is more of a risk (and testing effort) then I'm willing to take versus mapping out a few properties. I'll check out the connection string change too. I've attempted a fork but 4.6.2 isn't installed on my laptop and I can't get a failing unit test yet for the decimal?
conversion.
Version: 6.7.2
When using Dapper's
connection.QueryAsync<ModelClass>(commandDefintion)
with a property ofdecimal?
, the below error gets thrown on mapping. Clickhouse table schema includes aNullable(Decimal(18, 2))
property that has it's value set to123.00