.NET Core 6查询可空TimeOnly字段时Ticks参数异常问题
解决.NET Core 6中查询可空TimeOnly字段时的Ticks范围异常
问题原因
这个异常是因为数据库中TimeEnd字段存储的值超出了TimeOnly类型的合法范围——TimeOnly仅支持00:00:00.0000000到23:59:59.9999999之间的时间(对应Ticks范围0到TimeOnly.MaxValue.Ticks)。常见触发场景:
- 数据库中存储了
24:00:00这类非法时间值 - 数据库字段类型与
TimeOnly的映射存在兼容问题(部分驱动会将特殊时间值转换为超出范围的Ticks) - EF Core 6早期版本对可空
TimeOnly的映射存在bug
解决方案
1. 排查并清理数据库非法值
先定位数据库中table1的非法记录:
- 以SQL Server为例,执行以下查询筛选异常值:
SELECT * FROM table1 WHERE TimeEnd >= '24:00:00' OR TimeEnd < '00:00:00'
将这些非法值修正为合法时间(比如把24:00:00改为00:00:00)或设为NULL。
2. 在查询中直接处理异常值
如果暂时无法修改数据库,可在LINQ查询中过滤或转换非法值:
var result = await (from s in _unitOfWork.Context.table1 select new { Id = Convert.ToString(s.EventId), // 仅保留合法的TimeOnly值,非法值设为NULL EndTimeC = s.TimeEnd.HasValue && s.TimeEnd.Value.Ticks <= TimeOnly.MaxValue.Ticks ? s.TimeEnd : null, DateC = s.Date, StartTimeC = s.TimeBegin, Systemmodstamp = s.ModifiedDate }).ToListAsync();
3. 配置EF Core值转换器处理映射问题
在DbContext的模型配置中添加值转换器,自动将数据库中超范围的时间转换为NULL:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<table1>() .Property(t => t.TimeEnd) .HasConversion( // 写入数据库时转换为TimeSpan v => v.HasValue ? v.Value.ToTimeSpan() : (TimeSpan?)null, // 读取时仅转换合法的TimeSpan为TimeOnly,非法值设为NULL v => v.HasValue && v.Value.TotalTicks <= TimeOnly.MaxValue.Ticks ? TimeOnly.FromTimeSpan(v.Value) : null); }
4. 升级EF Core补丁版本
如果是EF Core 6早期版本的bug导致的问题,升级到.NET Core 6的最新补丁版本(如6.0.25及以上)可解决部分映射兼容性问题。
内容的提问来源于stack exchange,提问作者Dx Developer
相关产品推荐
相关产品推荐

