C#如何正确映射SQL Server返回的格式化Datetime值
问题根因
- 列名映射缺失:你C#代码中拼接的SQL语句里,
FORMAT(DS.CreatedAt, 'dd/MM/yyyy - hh:mm:ss')没有加AS CreatedAt别名,Dapper无法将该查询结果列和模型的CreatedAt属性对应,自动赋值了DateTime类型的默认值0001-01-01T00:00:00。 - 类型不匹配:
FORMAT函数返回的是字符串类型,但你的模型中CreatedAt是DateTime结构,类型不匹配无法直接映射。 - 额外风险:直接拼接
DossierId到SQL语句存在SQL注入漏洞,建议改为参数化查询。
解决方案1(推荐:保留DateTime类型,C#侧处理格式化)
该方案更符合开发规范,数据层只负责返回原生时间数据,格式化逻辑放在业务/展示层处理,后续调整格式不需要修改SQL。
操作步骤
- 修改SQL语句,直接返回原生DateTime字段,同时改为参数化查询:
string Sql = @" SELECT StatusId, DS.CreatedAt, DS.CreatedBy, S.[Text] FROM [Inspection].[Dossier_Status] DS INNER JOIN [DT_Inspection].[Status] S ON S.Id = StatusId WHERE DossierId = @DossierId ORDER BY DS.CreatedAt DESC";
- 执行查询时传入参数:
var result = await sqlConnection.QueryAsync<Dossier_StatusVUE>(Sql, new { DossierId = DossierId });
- 需要展示指定格式时,直接对DateTime属性格式化即可:
// 输出格式:dd/MM/yyyy - hh:mm:ss string formatCreatedAt = yourModel.CreatedAt.ToString("dd/MM/yyyy - hh:mm:ss");
如果是API返回给前端自动序列化需要该格式,可在Program.cs中配置JSON序列化规则:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new System.Text.Json.Serialization.JsonStringDateTimeConverter("dd/MM/yyyy - hh:mm:ss")); });
解决方案2(匹配现有SQL格式化逻辑,修改模型)
如果你一定要在SQL侧完成格式化,可按以下步骤调整:
- 修改模型的
CreatedAt属性类型为string:
public string Text { get; set; } public int StatusId { get; set; } public string CreatedAt { get; set; } // 改为string类型匹配SQL返回的格式化字符串
- 给SQL查询的格式化列加
AS CreatedAt别名,同时改为参数化查询:
string Sql = @" SELECT StatusId, FORMAT(DS.CreatedAt, 'dd/MM/yyyy - hh:mm:ss') AS CreatedAt, DS.CreatedBy, S.[Text] FROM [Inspection].[Dossier_Status] DS INNER JOIN [DT_Inspection].[Status] S ON S.Id = StatusId WHERE DossierId = @DossierId ORDER BY DS.CreatedAt DESC";
内容的提问来源于stack exchange,提问作者AliCa
相关产品推荐
相关产品推荐

