.NET 7+EF+PostgreSQL种子数据时报UTC时间格式错误
解决Npgsql EF Core种子数据UTC时间报错问题
问题根源
你遇到的InvalidCastException本质是:虽然JSON里的时间是带Z的UTC格式,但Newtonsoft.Json默认会将其反序列化为DateTimeKind.Local类型的DateTime,而PostgreSQL的timestamp with time zone字段要求传入的必须是明确标记为UTC的DateTime(DateTimeKind.Utc),EF Core生成迁移SQL字面量时就会触发这个错误。
解决方法
方案1:修改JSON反序列化配置(推荐)
在反序列化JSON时,指定DateTimeZoneHandling.Utc,让Newtonsoft.Json直接把带Z的时间解析为UTC时间:
public void Seed() { var jsonSettings = new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.Utc }; var dataJson = JsonConvert.DeserializeObject<List<DataTable>>( File.ReadAllText(@".\Database\Seed_Data.json"), jsonSettings ); modelBuilder.Entity<DataTable>().HasData(dataJson); }
方案2:手动修正DateTime的Kind
如果不想修改全局反序列化设置,可以在反序列化后,手动将每个OrderDate的Kind标记为UTC:
public void Seed() { var dataJson = JsonConvert.DeserializeObject<List<DataTable>>(File.ReadAllText(@".\Database\Seed_Data.json")); // 修正每个时间的Kind为UTC foreach (var item in dataJson) { item.OrderDate = DateTime.SpecifyKind(item.OrderDate, DateTimeKind.Utc); } modelBuilder.Entity<DataTable>().HasData(dataJson); }
方案3:在实体类上配置JsonConverter
给OrderDate属性添加特性,指定反序列化时按UTC处理:
public class DataTable { public Guid Id { get; set; } [JsonConverter(typeof(IsoDateTimeConverter))] [JsonProperty(PropertyName = "OrderDate")] public DateTime OrderDate { get; set; } public string Product { get; set; } }
注:IsoDateTimeConverter默认会正确解析带Z的UTC时间为
DateTimeKind.Utc。
验证方法
可以在反序列化后添加调试代码,确认DateTime的Kind是否为Utc:
foreach (var item in dataJson) { Console.WriteLine(item.OrderDate.Kind); // 应该输出Utc }
内容的提问来源于stack exchange,提问作者Scottish Smile
相关产品推荐
相关产品推荐

