You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core EF连接MySQL时time类型返回拆分对象如何解决

问题根因

MySQL time类型在EF Core中默认映射为C# TimeSpan类型,你看到的嵌套结构化对象是JSON序列化器处理TimeSpan的默认行为,和数据库映射、EF Core逻辑无关,不需要修改生产库的字段类型,仅调整序列化配置即可解决。

推荐方案:全局配置TimeSpan序列化格式(无侵入,不影响数据库读写)

该方案不需要修改实体类、EF Core映射配置,仅调整Web API的JSON序列化规则,所有接口的TimeSpan字段都会自动输出为HH:mm:ss格式字符串。

  1. 自定义System.Text.Json的TimeSpan转换器,新建TimeSpanJsonConverter.cs:
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

public class TimeSpanJsonConverter : JsonConverter<TimeSpan>
{
    private const string StandardTimeFormat = @"hh\:mm\:ss";

    public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return TimeSpan.ParseExact(reader.GetString()!, StandardTimeFormat, CultureInfo.InvariantCulture);
    }

    public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(StandardTimeFormat, CultureInfo.InvariantCulture));
    }
}
  1. 注册转换器到全局JSON配置:
  • .NET 6+ 版本修改Program.cs:
builder.Services.AddControllers()
    .AddJsonOptions(opt =>
    {
        opt.JsonSerializerOptions.Converters.Add(new TimeSpanJsonConverter());
    });
  • .NET Core 3.1/.NET 5 版本修改Startup.cs的ConfigureServices方法:
services.AddControllers()
    .AddJsonOptions(opt =>
    {
        opt.JsonSerializerOptions.Converters.Add(new TimeSpanJsonConverter());
    });

配置完成后重启项目,trnTime、prevTime字段就会返回"17:11:00"、"00:00:00"格式的字符串,完全符合预期,且数据库读写逻辑不受任何影响。

备选方案:单独接口用DTO映射

如果不想全局修改序列化规则,可针对该接口单独定义返回DTO,手动格式化TimeSpan字段:

  1. 定义返回用的DTO类:
public class DtrDto
{
    public int LineNo { get; set; }
    public string EmpCode { get; set; }
    public int? LogType { get; set; }
    public DateTime? TrnDate { get; set; }
    public string TrnTime { get; set; }
    public DateTime SvrTime { get; set; }
    public string PrevTime { get; set; }
    public DateTime? PrevDate { get; set; }
}
  1. 修改Controller接口,查询后映射为DTO返回:
[HttpGet("getalldtr")]
public ActionResult<IEnumerable<DtrDto>> GetAllDtr()
{
    return _context.Dtrs.Take(100)
        .Select(x => new DtrDto
        {
            LineNo = x.LineNo,
            EmpCode = x.EmpCode,
            LogType = x.LogType,
            TrnDate = x.TrnDate,
            TrnTime = x.TrnTime.ToString(@"hh\:mm\:ss"),
            SvrTime = x.SvrTime,
            PrevTime = x.PrevTime.ToString(@"hh\:mm\:ss"),
            PrevDate = x.PrevDate
        })
        .ToList();
}
避坑提醒
  • 不要直接把实体类里的TrnTime、PrevTime属性类型改成string,会破坏EF Core和MySQL time字段的映射,导致数据库读写报错。
  • 如果项目用Newtonsoft.Json替代默认的System.Text.Json,只需要安装对应版本的Microsoft.AspNetCore.Mvc.NewtonsoftJson包,注册时追加.AddNewtonsoftJson(opt => opt.SerializerSettings.Converters.Add(new TimeSpanConverter()))即可,Newtonsoft.Json自带的TimeSpan转换器默认就会序列化为HH:mm:ss格式。

内容的提问来源于stack exchange,提问作者Rak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 19:12:30