有没有办法在 Model 或 Dto 定义类中将 DateTimeOffset 更改为 UtcDateTime 或 LocalDateTime?

Posted

技术标签:

【中文标题】有没有办法在 Model 或 Dto 定义类中将 DateTimeOffset 更改为 UtcDateTime 或 LocalDateTime?【英文标题】:Is there a way to change the DateTimeOffset to UtcDateTime or LocalDateTime in Model or Dto definition classes? 【发布时间】:2022-01-12 04:11:15 【问题描述】:

我有一个使用实体框架的 .NET 6 Web API。一些端点接收包含 datetimeoffset 属性的对象,并且传入的值是本地日期时间的形式。

问题是,在最新版本的 PostgreSql 中,datetimeoffset 值只能采用 ...T+00 UTC 格式的 datetimeoffset 输入。因此,当我的值类似于 ...T+03 时,我无法将其写入数据库。

这是我的模型类

public class MyModel : BaseEntity

    public DateTimeOffset MyDate  get; set; 

这是我的 dto 类

public class Dto : BaseDto

    public DateTimeOffset MyDate  get; set; 

临时解决方案

现在,我每次在我的服务类中向数据库发布和获取数据库时都会更改格式,如下所示:

发帖:

myDto.MyDate = myDto.MyDate.UtcDateTime;
var myModel = _mapper.Map<MyModel>(myDto);
await _unitOfWork.MyModelContext.CreateAsync(myModel);
await _unitOfWork.SaveAsync();
//...

获取:

var myModels = await _unitOfWork.MyModelContext.GetAll();
foreach(var myModel in myModels)
    myModel.MyDate = myModel.MyDate.LocalDateTime;
//...

//or

var myModel = await _unitOfWork.MyModelContext.GetById(id);
myModel.MyDate = myModel.MyDate.LocalDateTime;
//...

我知道这是一种不好的方法。 我想知道是否可以在我的 Dtos 或模型中进行此操作,这样我就不需要在每个服务上进行此操作。

我也愿意接受其他建议。

【问题讨论】:

这个答案能帮到你吗? ***.com/questions/39418323/… 好吧,我也想到了这一点,但我不确定在 Save() 中使用它,因为我只有几个使用 DateTime/DateTimeOffset 属性的模型。如果我在 Save() 中实现一个控件,它是否适用于每个数据库插入/更新?我认为这不如在服务中转换它有效(虽然肯定更通用)。感谢您的评论,我还意识到我不应该在 API 中从 DateTimeOffset 转换为 Local,因为那样它总是需要 API 的时区。相反,我应该在客户端进行。 感谢您的回复,我认为在客户端转换日期时间偏移量也是一个不错的选择。起初我想在模型属性上找到类似 [Convert Datetime] 标记的解决方案,但失败了。 我尝试了类似的方法来获取和设置模型和 dto,但也失败了。 【参考方案1】:

您需要创建一个custom type converter,如下所示。

public class DateTimeOffSetTypeConverter : ITypeConverter<DateTimeOffset, DateTimeOffset>
        
            public DateTimeOffset Convert(DateTimeOffset source, DateTimeOffset destination, ResolutionContext context)
            
                destination = source.UtcDateTime;
                return destination;
            
        

然后在你的映射配置类中定义它。

var configuration = new MapperConfiguration(cfg => 
      
      cfg.CreateMap<DateTimeOffset, DateTimeOffset>().ConvertUsing(new DateTimeOffSetTypeConverter());
      
      //your mapping configurations
    );

【讨论】:

这就是我要找的。谢谢你的回答。我添加了自定义类型转换器,因为我使用“Profiles”进行自动映射器配置,所以我刚刚将此行添加到我的相关配置文件类中,如下所示:“CreateMap().ConvertUsing(new DateTimeOffSetTypeConverter());”您对网络应用程序部分也有任何建议吗?从API接收到对象以显示当地时间的UTC时间后,我应该如何处理它?现在我在 web 应用程序的相关控制器中实现了它,但我不想在 foreach 中实现它 我认为如果您将列表设置为分页,则使用 foreach 循环并仅更改一个值是合适的。但也许你可以使用 Linq 的 ForEach 方法yourList.ForEach(c =&gt; c.MyDate = c.MyDate.ToLocalTime());

以上是关于有没有办法在 Model 或 Dto 定义类中将 DateTimeOffset 更改为 UtcDateTime 或 LocalDateTime?的主要内容,如果未能解决你的问题,请参考以下文章

DTO

在 TypeScript 和 NestS 中将类转换为类/对象(实体到 DTO)

如何将 Grails 域类映射到 DTO?

(扫盲)DTO数据传输对象

类或集合的转换(model-dto之间的转换)

在 Sequelize 中将模型的条件与其关联的条件结合起来