RepoDB
RepoDB copied to clipboard
Bug: TimeSpan? property data type mapping fails with System.Data.SqlClient
Bug Description
When using System.Data.SqlClient with RepoDb Batch Operations (InsertAllAsync, UpdateAllAsync, MergeAllAsync) to batch update data in Sql Server using at TimeSpan? model property an unexpected error occurs.
The properties are TimeSpan? nullable properties on the Model, and the SQL Server columns are time(7) types...
Exception Message:
Failed to convert parameter value from a TimeSpan to a DateTime. Inner Exception: Object must implement IConvertible
Schema and Model:
Please share to us the schema of the table (not actual) that could help us replicate the issue if necessary.
//Sample Model:
public class TestTable {
public int Id { get; set; }
public TimeSpan? ItemStartTime{ get; set; }
public TimeSpan? ItemEndTime{ get; set; }
}
--Sampel DB Schema:
CREATE TABLE [dbo].[TestTable](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ItemStartTime] [time](7) NULL,
[ItemEndTime] [time](7) NULL,
CONSTRAINT [PK__AdwordCa__3214EC07E2A92D2C] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Library Version: Using latest RepoDB Sql Server Library v1.12.7 and RepoDb.SqlServer v1.1.3
Per our conversation on Gitter, our initial discussion yielded the following findings:
- Microsoft documentation states for
DbType Enumit saysDbType.Time (17) -- A type representing a SQL Server DateTime value. If you want to use a SQL Server time value, use Time.And then if you look atSqlDbType Enumit saysSqlDbType.Time (32) -- Time data based on a 24-hour clock. Time value range is 00:00:00 through 23:59:59.9999999 with an accuracy of 100 nanoseconds. Corresponds to a SQL Server time value.Of which we expect that the correct mapping toSqlDbType.Timewould automatically occur. - This does work as expected with
Microsoft.Data.SqlClient, but fails withSystem.Data.SqlClient. - You were able to successfully reproduce the issue...

Thanks!
Good News:
As discussed on Gitter, we cannot easily change the legacy code base from using System.Data.SqlClient (yet; it's on our strategic plan though), however we were able to resolve this with the use of [SystemSqlServerTypeMap(SqlDbType.Time)] attribute on the offending model properties.
Is there a way to do this via Global Type Mapping configuration?
Unfortunately I was not able to get it to work with a global configuration via FluentMapper or TypeMapper which would help ensure that it's resolved universally...