Ich versuche, Dapper Schnittstelle zu einem vorhandenen Datenbankformat zu verwenden, das eine Tabelle mit einer Dauer aufweist, die als Ticks in einer BIGINT-Spalte codiert wird. Wie sage ich Dapper, um die TimeSpan
-type-Eigenschaft meines POCO Ticks zuzuordnen, wenn es in die Datenbank eingefügt wird und von der Datenbank liest?Mapping TimeSpan in SQLite und Dapper
Ich habe versucht, den Typ der Karte für TimeSpan
-DbType.Int64
einzustellen:
SqlMapper.AddTypeMap(typeof(TimeSpan), DbType.Int64);
Und ich habe erstellt auch eine ITypeHandler
, aber die SetValue
Methode aufgerufen wird nie:
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;
}
}
Hier mein POCO:
public class Task
{
public TimeSpan Duration { get; set; }
// etc.
}
Wh en eine einfache Insert-Anweisung wie folgt ausführen:
string sql = "INSERT INTO Tasks (Duration) values (@Duration);";
Und die POCO als Objekt vorbei einzufügen:
Task task = new Task { Duration = TimeSpan.FromSeconds(20) };
connection.Execute(sql, task);
Ich erhalte diese Ausnahme:
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
Wenn ich die TimeSpan
verlassen Typ Mapping wie es ist (es ist standardmäßig DbType.Time
), es schreibt die String-Version der TimeSpan
, dh `00: 00: 20.000", was nicht hilfreich ist, da es nicht die fo entspricht rmat der anderen Daten in der Spalte.
Ich habe immer dieses Problem gelöst, indem eine zweite Eigenschaft erstellen, die die Übersetzung tut vom DB-Typ zu meinem Typ. – juharr
Warum der Downvote ...? –