如何在Entity Framework中存储负TimeSpan值?
解决Entity Framework存储超出0-24小时范围TimeSpan的问题
下面是几种实用的解决办法,按需选择:
方案1:转成整数(总秒数/毫秒数)存储
把TimeSpan转成long类型的总秒数(或毫秒数),EF对整数类型的支持完全没问题,不管正负还是超24小时都能存。业务层用[NotMapped]标记的TimeSpan属性做转换,不用手动处理数值:
public class Shift { // 数据库里存的是long类型的整数 public long OffsetSeconds { get; set; } public long DurationSeconds { get; set; } // 业务逻辑用的TimeSpan属性,不映射到数据库 [NotMapped] public TimeSpan StartOffset { get => TimeSpan.FromSeconds(OffsetSeconds); set => OffsetSeconds = (long)value.TotalSeconds; } [NotMapped] public TimeSpan Duration { get => TimeSpan.FromSeconds(DurationSeconds); set => DurationSeconds = (long)value.TotalSeconds; } }
方案2:用EF Core自定义值转换器(推荐)
如果用的是EF Core,直接给TimeSpan属性配置值转换器,让EF自动完成TimeSpan和整数的双向转换,业务层完全不用关心转换逻辑:
// 在你的DbContext的OnModelCreating方法里配置 protected override void OnModelCreating(ModelBuilder modelBuilder) { // 定义转换器:TimeSpan转总秒数存,读的时候转回来 var timeSpanConverter = new ValueConverter<TimeSpan, long>( span => (long)span.TotalSeconds, seconds => TimeSpan.FromSeconds(seconds)); // 给对应的属性绑定转换器 modelBuilder.Entity<Shift>() .Property(s => s.StartOffset) .HasConversion(timeSpanConverter); modelBuilder.Entity<Shift>() .Property(s => s.Duration) .HasConversion(timeSpanConverter); } // 实体类直接用TimeSpan属性就行 public class Shift { public TimeSpan StartOffset { get; set; } public TimeSpan Duration { get; set; } }
方案3:用DateTime存储(不推荐)
如果实在有特殊需求,可以把TimeSpan转成相对于某个基准时间的DateTime(比如DateTime.MinValue),但这种方式可读性差,负偏移还可能触发DateTime溢出,风险高,尽量别用:
public class Shift { public DateTime OffsetDateTime { get; set; } [NotMapped] public TimeSpan StartOffset { get => OffsetDateTime - DateTime.MinValue; set => OffsetDateTime = DateTime.MinValue.Add(value); } }
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

