在SQLite和Dapper中映射TimeSpan

Pat*_*irk 9 c# sqlite orm system.data.sqlite dapper

我正在尝试使用Dapper连接到现有的数据库格式,该格式具有在BIGINT列中编码为刻度的持续时间的表.TimeSpan在插入和读取数据库时,如何告诉Dapper将我的POCO的-typed属性映射到滴答?

我试着设置类型映射TimeSpanDbType.Int64:

SqlMapper.AddTypeMap(typeof(TimeSpan), DbType.Int64);
Run Code Online (Sandbox Code Playgroud)

我也创建了一个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的POCO:

public class Task
{
    public TimeSpan Duration { get; set; }

    // etc.
}
Run Code Online (Sandbox Code Playgroud)

执行这样的简单插入语句时:

string sql = "INSERT INTO Tasks (Duration) values (@Duration);";
Run Code Online (Sandbox Code Playgroud)

并将POCO作为要插入的对象传递:

Task task = new Task { Duration = TimeSpan.FromSeconds(20) };
connection.Execute(sql, task);
Run Code Online (Sandbox Code Playgroud)

我得到这个例外:

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
Run Code Online (Sandbox Code Playgroud)

如果我TimeSpan按原样保留类型映射(默认为DbType.Time),它会写入字符串版本TimeSpan,即"00:00:20.000",这没有用,因为它与其他数据的格式不匹配柱.

juh*_*arr 3

您可以执行以下操作吗?

public class Task
{
    public TimeSpan Duration { get; set; }
    public long Ticks 
    { 
        get { return Duration.Ticks; }
        set { Duration = new TimeSpan(value); }
    }
    // etc.
}

string sql = "INSERT INTO Tasks (Duration) values (@Ticks);";
Run Code Online (Sandbox Code Playgroud)