繁体   English   中英

实体框架,代码优先和日期时间

[英]Entity framework, code first and datetimes

因此,我有一个非常庞大的项目,其中包含大量的DI。 该解决方案的架构过于复杂,非常复杂。 该解决方案是使用EF Code first方法(不存在模型)开发的,并且对于大多数表对象,它包含一个或多个DateTime属性。

它已经到了(过程很晚!),我需要将日期时间转换为UTC格式。 对于数据库中的现有数据,我可以运行SQL脚本并轻松完成一次转换工作。

但是对于将来和正在运行的代码,从UTC格式TO和FROM DB转换(插入,更新和选择时)并应用偏移量(即-2小时)以显示给UTC的最佳方法是什么? UI正确的日期时间? (即UTC到PST)

要记住的一件事是,有很多代码,很多嵌套的和深层的埋藏代码,我希望能够找到最简单的方法,而无需触摸所有对象,接口等...即可将其全部转换为在EF中发出SQL命令时的UTC。 我想使用SQL Server方法在存储时转换为UTC,而在检索而不是在.NET级别时从UTC转换。

任何想法或见解将不胜感激。

没有代码可在此处显示,因为这不是一个真正的编码问题,而是更多有关如何使EF执行(在调用SQL之前构造查询时)如何进行往返于UTC和返回具有正确日期时间的结果集。

谢谢。

您可以重写EF SaveChanges()方法来检查是否有任何修改的实体具有日期,并将其转换为UTC日期。 这是放置在数据库上下文中的示例代码。

public override int SaveChanges()
{
    var selectedEntityList = ChangeTracker.Entries()
                            .Where(x => x.Entity is EntityInformation &&
                            (x.State == EntityState.Added || x.State == EntityState.Modified));

    foreach (var entity in selectedEntityList)
    {

        ((EntityInformation)entity.Entity).Date = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now.ToUniversalTime());
    }

    return base.SaveChanges();
}

因此,这将检查是否有任何修改/添加的实体具有名为Date的属性,并将其设置为UTC日期。 这可能不是您所需要的,但这是您应采用的解决方案,以便有一个将日期转换为UTC的地方。

一些东西:

  • 是的,您的数据库应存储UTC,是的,您可以将其转换为特定时区,然后再显示在UI中。 但是,数据访问层不是执行此操作的正确位置。 数据模型应准确反映数据库中的内容。

    如果您只是将时间戳转换为输入或显示,则最佳做法是在进场时尽早进行此操作,并在出路时尽早进行此操作。 在某些情况下,这意味着转换是在控制器或视图模型中完成的,而在另一些情况下,则一直将其下推到客户端并使用JavaScript完成。 在哪里做完全取决于您,但是在数据访问层通常不适合这样做。

  • 有时(但并非总是如此)在您的域层中进行转换是有意义的,尤其是当域涉及基于本地日期或时间做出的决策时。 如果您的域可以准确地模拟不同时区的时间,这将很有帮助。 Noda Time确实非常有用,因为它包含专用类型,例如InstantLocalDateZonedDateTime

  • 您希望在一处执行此操作,而不必触摸代码的所有部分,这是可以理解的-但我可以从经验中告诉您,采用“一刀切”的方法最终会回来困扰你 事实是,“始终使用UTC”的常见建议是短视的。 最终,您将遇到需要本地时间值的情况。 并非所有使用DateTime的目的都是相同的。 UTC通常是适当的,但有时不合适。 如果您找到一种在体系结构中全局应用UTC转换的方法,那么您将放弃对此进行控制的能力。

    特别是, 时间戳记对于UTC(或DateTimeOffset )是一个很好的方案,但调度不是。 日程安排通常基于当地时间,例如闹钟每天早上8:00(在暗示的当地时间)关闭,或者在东部时间每周三的10:00 AM召开会议。

    另外,请考虑某些日期时间方案实际上只是一个没有时间的固定日期。 生日和工作周年纪念就是一个很好的例子。 请勿尝试将这些内容转换为UTC,否则最终可能会+/- 1天。

  • 另外,您说过您正在尝试转换为固定偏移量,但是您也说过要从UTC转换为PST。 您应该了解PST仅在一年的一部分时间内生效。 当夏令时生效时,太平洋时间切换到PDT。 要正确转换时区,您不能仅使用固定的偏移量。 转换需要确定-08:00或-07:00是否适合要转换的时间戳。 另请参见时区标签Wiki “时区!=偏移”。

希望对您有所帮助,并祝您项目顺利!

从EF 6开始,您可以使用拦截器并在DbCommand到达数据库之前对其进行修改。 https://msdn.microsoft.com/zh-cn/data/dn469464(v=vs.113).aspx#BuildingBlocks

public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 
{ 
    for (int i = 0; i < command.Parameters.Count; i++) {
            var param = command.Parameters[i];
            if (param.DbType == DbType.DateTime) {
                // Change param.Value here
            }
        }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM