我尝试使用Dapper与现有的数据库格式进行接口,该数据库格式有一个表,表中的持续时间被编码为BIGINT列中的刻度。在插入和阅读数据库时,如何告诉Dapper将POCO的TimeSpan
类型的属性Map到tick?
我尝试将TimeSpan
的类型Map设置为DbType.Int64
:
SqlMapper.AddTypeMap(typeof(TimeSpan), DbType.Int64);
我还创建了一个ITypeHandler
,但SetValue
方法从未被调用:
public class TimeSpanToTicksHandler : SqlMapper.TypeHandler<TimeSpan>
{
public override TimeSpan Parse(object value)
{
return new TimeSpan((long)value);
}
public override void SetValue(IDbDataParameter parameter, TimeSpan value)
{
parameter.Value = value.Ticks;
}
}
这是我的POCO:
public class Task
{
public TimeSpan Duration { get; set; }
// etc.
}
当执行一个简单的insert语句时:
string sql = "INSERT INTO Tasks (Duration) values (@Duration);";
并传递POCO作为要插入的对象:
Task task = new Task { Duration = TimeSpan.FromSeconds(20) };
connection.Execute(sql, task);
我得到这个例外:
System.InvalidCastException : Unable to cast object of type 'System.TimeSpan' to type 'System.IConvertible'.
at System.Convert.ToInt64(Object value, IFormatProvider provider)
at System.Data.SQLite.SQLiteStatement.BindParameter(Int32 index, SQLiteParameter param)
at System.Data.SQLite.SQLiteStatement.BindParameters()
at System.Data.SQLite.SQLiteCommand.BuildNextCommand()
at System.Data.SQLite.SQLiteCommand.GetStatement(Int32 index)
at System.Data.SQLite.SQLiteDataReader.NextResult()
at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)
at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery(CommandBehavior behavior)
at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery()
at Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, ref CommandDefinition command, Action`2 paramReader) in SqlMapper.cs: line 3310
at Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, ref CommandDefinition command) in SqlMapper.cs: line 1310
at Dapper.SqlMapper.Execute(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable`1 commandTimeout, Nullable`1 commandType) in SqlMapper.cs: line 1185
如果我保持TimeSpan
类型Map不变(默认为DbType.Time
),它将写入TimeSpan
的字符串版本,即`00:00:20.000”,这没有帮助,因为它与列中其他数据的格式不匹配。
3条答案
按热度按时间yrefmtwq1#
你能做以下事情吗?
k5ifujac2#
LinqToDB解决方案:
或者:
示例:
iq0todco3#
我还想在
TimeSpan
和DbType.Int64
之间进行转换,我还发现我的ITypeHandler
实现中的SetValue
方法从未被调用。我发现除了注册类型handler之外,我还必须删除
TimeSpan
和TimeSpan?
的类型map:使用Dapper 1.50.5。