Я пытаюсь использовать Dapper для взаимодействия с существующим форматом базы данных, который имеет таблицу с длительностью, закодированной как тики в столбце BIGINT. Как мне сообщить Dapper о том, чтобы сопоставить свой статус TimeSpan
PIPO с типом при вставке и чтении из базы данных?Сопоставление TimeSpan в SQLite и Dapper
Я попытался установить карту типа для TimeSpan
в 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.
}
Wh ан выполнения простого оператора вставки, как это:
string sql = "INSERT INTO Tasks (Duration) values (@Duration);";
И передавая ПОКО как объект для вставки:
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
(по умолчанию он равен DbType.Time
), он записывает строчную версию TimeSpan
, то есть `00: 00: 20.000", что не помогает, поскольку оно не соответствует fo rmat других данных в столбце.
Я всегда решается путем создания второго свойства, что делает перевод от типа DB до моего типа. – juharr
Почему downvote ...? –