如何修改DynamoDB .NET SDK默认行为,将DateTime存储为数字类型?
解决方案:自定义DynamoDB DateTime转换器(以数字类型存储)
可以重写AWS SDK for .NET的默认行为,通过自定义属性转换器实现DateTime以数字类型(N)存储,同时解决精度丢失和时区转换的问题。
1. 实现自定义DateTime转换器
创建实现IPropertyConverter接口的转换器,将DateTime转换为UTC时间的ticks值(以字符串形式存储为DynamoDB的N类型),读取时再还原为UTC类型的DateTime:
using Amazon.DynamoDBv2.DataModel; using System; public class DateTimeToTicksConverter : IPropertyConverter { public object FromEntry(DynamoDBEntry entry) { if (long.TryParse(entry.AsString(), out long ticks)) { // 强制生成UTC类型的DateTime,避免SDK自动转换为本地时间 return new DateTime(ticks, DateTimeKind.Utc); } throw new InvalidCastException("无法将DynamoDB条目转换为DateTime"); } public DynamoDBEntry ToEntry(object value) { if (value is DateTime dateTime) { // 统一转换为UTC时间后存储,消除时区差异 var utcDateTime = dateTime.ToUniversalTime(); // 以字符串形式存储ticks,对应DynamoDB的N类型 return new Primitive(utcDateTime.Ticks.ToString(), true); } throw new InvalidCastException("无法将值转换为DynamoDB条目"); } }
2. 在实体类中应用转换器
在需要的DateTime属性上标注DynamoDBProperty并指定自定义转换器:
[DynamoDBTable("YourTargetTable")] public class BusinessEntity { [DynamoDBHashKey] public string Id { get; set; } // 应用自定义转换器,将DateTime以ticks数字存储 [DynamoDBProperty(typeof(DateTimeToTicksConverter))] public DateTime CreatedTime { get; set; } }
3. 解决核心问题的验证
- 精度问题:存储的是完整的ticks值,读取后会还原出包含7位小数的
DateTime,原时间与取回时间对比会完全匹配。 - 时区问题:转换器强制以UTC时间存储和读取,避免SDK自动将UTC转换为本地时间的行为,保持时间一致性。
示例验证代码:
var originalUtcDate = DateTime.UtcNow; var entity = new BusinessEntity { Id = "test_id", CreatedTime = originalUtcDate }; // 保存到DynamoDB await context.SaveAsync(entity); // 取回实体 var retrievedEntity = await context.LoadAsync<BusinessEntity>("test_id"); // 对比结果为True,精度和时区都一致 Console.WriteLine(originalUtcDate == retrievedEntity.CreatedTime);
内容的提问来源于stack exchange,提问作者user246392
相关产品推荐
相关产品推荐

