dylan
March 21, 2022, 11:16am
1
I have a Time
column in SQL Server. Historically this would be mapped to a TimeSpan
in C# world. However I want to utilize the TimeOnly
property.
I have a definition that looks as follows:
Then in code:
However when saving this object I get the following exception:
When trying to read out the value, it is always “00:00:00”.
I am assuming I will need to implement some kind of converter to support this, but am not sure where to start or what exactly to convert between.
Can you please provide some assistance?
dylan
March 21, 2022, 11:30am
2
Does this make sense as a converter?
public class SqlServerTimeOnlyConverter : SqlServerTimeConverter
{
public override DbType DbType => DbType.Time;
public override object ToDbValue(Type fieldType, object value)
{
if (value is TimeOnly timeOnly)
{
return timeOnly.ToString("o");
}
else if (value is string str && TimeOnly.TryParseExact(str, "HH:mm:ss", out var time))
{
return time.ToString("o");
}
return base.FromDbValue(fieldType, value);
}
public override object FromDbValue(Type fieldType, object value)
{
object x = base.FromDbValue(fieldType, value);
if(x is TimeSpan ts)
{
return new TimeOnly(ts.Ticks);
}
return x;
}
}
mythz
March 21, 2022, 12:08pm
3
I wouldn’t override SqlServerTimeConverter.cs which uses the DateTime ADO .NET DbType for its TIME column. I’d copy ColumnDefinition
and inherit OrmLiteConverter directly.
dylan
March 21, 2022, 2:55pm
4
public class SqlServerTimeOnlyConverter : OrmLiteConverter
{
public override DbType DbType => DbType.Time;
public int? Precision { get; set; }
public override string ColumnDefinition => Precision != null
? $"TIME({Precision.Value})"
: "TIME";
public override object ToDbValue(Type fieldType, object value)
{
if (value is TimeOnly timeOnly)
{
return timeOnly.ToString("o");
}
else if (value is string str && TimeOnly.TryParseExact(str, "HH:mm:ss", out var time))
{
return time.ToString("o");
}
return base.FromDbValue(fieldType, value);
}
public override object FromDbValue(Type fieldType, object value)
{
if (value is TimeSpan ts)
{
return new TimeOnly(ts.Ticks);
}
return base.FromDbValue(fieldType, value);
}
}
mythz
March 21, 2022, 3:36pm
5
To be complete you’ll also want to override ToQuotedString()
to return the format that SQL Server natively understands for comparison of a TIME
column type in a non parameterized query, e.g. Where Column = '1:02:03'