17370845950

Dapper如何处理TimeSpan类型 Dapper映射SQL time类型
Dapper 默认不支持 TimeSpan 类型直接映射,因其内置类型处理器未覆盖 TimeSpan;需手动注册 ITypeHandler 实现 SQL Server 的 time 类型双向转换,或在 SQLite 中用 TEXT/INTEGER 替代并手动解析。

Dapper 默认不支持 TimeSpan 类型的直接映射,尤其在使用 SQLite 或某些数据库提供程序时(如 Microsoft.Data.Sqlite),TimeSpan 会被明确排除在自动转换列表之外。

为什么 Dapper 不原生映射 TimeSpan

SQL Server 的 time 类型逻辑上对应 .NET 的 TimeSpan,但 Dapper 的内置类型处理器只覆盖常见基础类型(intstringDateTime 等),而未包含 TimeSpan。官方文档与源码注释中已明确说明:它不能处理 TimeSpan、DateTimeOffset、Guid 等类型,需手动注册处理器。

SQL Server 中 time → TimeSpan 的正确映射方式

在 SQL Server 场景下,可借助自定义 ITypeHandler 实现双向转换:

  • 写入时:将 TimeSpan 转为 TimeSpan.ToString("g") 或直接传给 SqlParameter 并设 SqlDbType.Time
  • 读取时:从 SqlDataReader.GetTimeSpan()GetValue() 后解析字符串/TimeSpan
  • 注册处理器:调用 SqlMapper.AddTypeHandler(typeof(TimeSpan), new TimeSpanHandler())

SQLite 等轻量数据库的替代方案

SQLite 没有原生 time 类型,通常用 TEXT(如 "14:30:00")或 INTEGER(秒数)存储时间跨度。此时建议:

  • 读取时用 ParseExactTimeSpan.FromSeconds 手动转换
  • 避免依赖自动映射,改用 DynamicParameters 显式控制参数类型
  • 若频繁使用,封装一个轻量 TimeSpanHandler 并全局注册

实用小技巧:不用自定义处理器也能临时处理

对简单场景,可绕过映射限制:

  • 查询时用 Query 或匿名类型,再手动转 TimeSpan
  • 插入时把 TimeSpan.TotalSecondsint 存,读取后再构造 TimeSpan
  • DateOnly/TimeOnly(.NET 6+)替代部分 TimeSpan 语义,Dapper 支持更好

基本上就这些。关键不是“能不能”,而是“要不要自己搭桥”——Dapper 把控制权留给你,也正因如此,它轻、快、不越界。