I let ServiceStack OrmLite (5.1.1) create the table, and persist the object, that contains a TimeSpan:
// ...
public TimeSpan _Jobs_VehicleNotificationTime { get; set; }
// ...
When I try to read it back, I get this error:
System.InvalidCastException: 'Invalid cast from 'System.Int64' to 'System.TimeSpan'.'
The value is persisted as a long
it seems:
but I get this when using the FromObjectDictionary
method:
Error is:
at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
at ServiceStack.PlatformExtensions.ObjectDictionaryFieldDefinition.SetValue(Object instance, Object value)
at ServiceStack.PlatformExtensions.FromObjectDictionary(IReadOnlyDictionary`2 values, Type type)
at tWorks.Core.CoreServerCommons.Handlers.OrmLiteDbHandler.<>c__DisplayClass65_1.<ReadObjects>b__1(Dictionary`2 x) in D:\[GIT]\Core\CoreServerCommons\Handlers\DbHandlers\OrmLite\OrmLiteDbHandler.cs:line 577
Is this a bug or am I missing something?
I think I have resolved the issue. Maybe @mythz can tell me if this is completely wrong, but it seems to work:
Implement your own TimeSpanAsIntConverter
I first dismissed that idea, as I wrongly interpreted Mythz to the effect of Converters were not relevant or were not executed if using the Untyped API. When I did implement the TimeSpan converter, it worked just as expected:
namespace Commons
{
public class MyTimeSpanConverter : TimeSpanAsIntConverter
{
public override string ColumnDefinition => "TIME";
public override DbType DbType => DbType.Time;
public override object ToDbValue(Type fieldType, object value)
{
TimeSpan timespan = (TimeSpan)value;
return timespan;
}
}
}
Then, when using that converter, the table is correctly created with the TIME
type instead of bigint, and when persisted, it all looks OK:
Test code:
public void Test()
{
Customer c = new Customer() { Username = "TED ÅÄÖ", DeletedTime = DateTime.MaxValue, MyTimeSpan = new TimeSpan(1, 30, 0) };
CoreObject co = c;
long id;
using (IDbConnection db = _dbFactory.Open())
{
var typedApi = db.CreateTypedApi(co.GetType());
id = typedApi.Insert(co, selectIdentity: true);
};
using (IDbConnection db = _dbFactory.Open())
{
string tableName = co.GetType().GetModelMetadata().ModelName;
List<Dictionary<string, object>> results = db.Select<Dictionary<string, object>>($"SELECT * FROM {tableName} where id={id}");
List<CoreObject> coreObjects = results.Map(x => (CoreObject)x.FromObjectDictionary(co.GetType()));
}
}
This seems to resolve at least this issue for me - my TimeSpans work as expected.