我正在编写一个新库,以便我们的内部项目可以连接到各种 SAP Business One 数据库。一段时间以来,我们一直在使用 PetaPoco,它可以配置为很好地处理 HanaDb,但我一直将 Dapper 视为更新的、可能更简单的 ORM。问题是我不知道如何将其配置到 HanaDB。
在我们的代码中,只要我们使用双引号来分隔所有字段,就可以在 Microsoft SQL 目标和 HanaDB 目标上使用相同的 SQL 查询。这是可能的,因为可以配置 PetaPoco,以便我们的查询中的参数引用(例如“@CardCode”)可以在 HANA 上运行,我们可以在提供程序中配置 HANA 的冒号字符。
使用 PetaPoco 还可以添加自定义映射来处理 HANA 特有的
HanaDecimal
类型。
我想知道是否有人知道是否可以以类似的方式配置 Dapper,即
HanaDecimal
我看到一些代码表明 Dapper.Contrib 可以更改前缀,但我没有使用它 - 听起来好像该设置适用于进程中的所有连接(不仅仅是 HANA 连接),并且只允许使用冒号前缀,它不会隐藏冒号前缀的使用,所以它可能不是我正在寻找的。
我可能只能在仅 SQL 的项目上使用 Dapper,但我希望我能让它为我工作。
非常感谢任何帮助。
更新:我尝试添加 SQLMapper.TypeHandler,但这并不是我想要的解决方案。 TypeHandle 处理 Poco 具有特定非内在类型(例如 Role 类)的情况,但使用 HanaDb,实际的 DB 连接器将 Decimal Columns 读取为
HanaDecimal
类型。 HanaDecimal
类型实际上需要映射到 Poco 中的“小数”。
我可以使用
HanaDecimal
将 SqlMapper.TypeHandler<decimal>
映射到“十进制”,但理论上我可以将我的目标属性指定为十进制、双精度、浮点甚至 int、long、uint、ulong 等。所以我必须编写一大堆映射器。
Dapper 是否有一种基于传入对象类型而不是 POCO 上的目标类型触发的映射器?或者甚至更好的机制可以在传入时触发,但也可以说明目标类型(这就是 PetaPoco 所拥有的)。
目前看来,我必须为大量数字类型编写自定义映射器 - 这不会减慢整个过程吗?
马克
我最终添加了通过 SqlMapper.AddTypeHandler 注册的这些类(如下) - 这是我能想到的唯一方法。如果有人有更好的解决方案,请告诉我 - 干杯。
public class HanaDecimalToDecimalTypeHandler : SqlMapper.TypeHandler<decimal>
{
public override decimal Parse(object value)
{
return (value as HanaDecimal?) != null ? ((HanaDecimal)value).ToDecimal() : Convert.ToDecimal(value);
}
public override void SetValue(IDbDataParameter parameter, decimal value)
{
parameter.Value = value;
}
}
public class HanaDecimalToDoubleTypeHandler : SqlMapper.TypeHandler<double>
{
public override double Parse(object value)
{
return (value as HanaDecimal?) != null ? (double)((HanaDecimal)value).ToDecimal() : Convert.ToDouble(value);
}
public override void SetValue(IDbDataParameter parameter, double value)
{
parameter.Value = value;
}
}
public class HanaDecimalToLongTypeHandler : SqlMapper.TypeHandler<long>
{
public override long Parse(object value)
{
return (value as HanaDecimal?) != null ? (long)((HanaDecimal)value).ToDecimal() : Convert.ToInt64(value);
}
public override void SetValue(IDbDataParameter parameter, long value)
{
parameter.Value = value;
}
}
public class HanaDecimalToIntTypeHandler : SqlMapper.TypeHandler<int>
{
public override int Parse(object value)
{
return (value as HanaDecimal?) != null ? (int)((HanaDecimal)value).ToDecimal() : Convert.ToInt32(value);
}
public override void SetValue(IDbDataParameter parameter, int value)
{
parameter.Value = value;
}
}