在写入数据库时​​使用DateTime.Now时的Incer

时间:2011-06-03 17:56:53

标签: .net sql-server nhibernate entity-framework

well known在数据库中,您应该以通用时间坐标存储日期。

我正在寻找一种方法来了解开发人员何时在写入数据库时​​误用DateTime.Now。

我们正在使用Sql Server 2008,使用EF4或nHibernate 3.0。

当它包含低级别层的时区信息时,是否可以拦截日期时间的值,例如在Sql Server或NH / EF中?

6 个答案:

答案 0 :(得分:3)

您可以添加以下事件侦听器:

public class DateTimeEventListener : IPreUpdateEventListener,
                                     IPreInsertEventListener
{
    public bool OnPreUpdate(PreUpdateEvent e)
    {
        foreach (var value in e.State)
            if (value is DateTime && ((DateTime)value).Kind != DateTimeKind.Utc)
                throw new Exception("Non-UTC DateTime used");
    }

    public bool OnPreInsert(PreInsertEvent e)
    { /*Same as OnPreUpdate*/ }
}

(这是完全未经测试的,可能会因从数据库中检索到的值而失败。用作起始点)

答案 1 :(得分:0)

您可以在数据库中编写一个触发器,当您预期现在的DateTime现在不在UTC附近时,会记录(或执行其他操作)。

您可以将EF或NHibernate图层的默认日期字段设置为UTC Now,以便开发人员无需设置它们。

可能更好,您可以只搜索DateTime.Now的代码并查看用法。

答案 2 :(得分:0)

我认为在NHibernate中你可以使用拦截器类覆盖OnSave上的OnLoad等基本方法。您可以尝试拦截属性类型并在插入db。之前管理您的日期。

看这里:

http://knol.google.com/k/fabio-maulo/nhibernate-chapter-11-interceptors-and/1nr4enxv3dpeq/14#

答案 3 :(得分:0)

处理不良数据的关键是尽早消除它。当你进入数据库层时,做任何有用的事情都为时已晚。

在运行时检测SQL查询中DateTime.Now的使用可能是不可能的。您最好通过代码并消除DateTime.Now的所有用途。到处。设置编码标准,以便整个程序中的所有日期和时间都以UTC表示,除非必须以本地时间或其他时区输出。对于这个问题,这将是一个更好的长期解决方案。

答案 4 :(得分:0)

抛开日期是否应该以UTC存储的论点,在代码中检查这些类型的东西的地方是在构建过程中,或者使用预提交钩子失败。

后者只允许开发人员提交符合您标准的代码。在数据库层做这件事太晚了,IMO。

答案 5 :(得分:0)

您不应该引入代码来强制执行开发人员编码风格的规则。您不必要地在应用中引入了开销。有很多方法可以解决这个问题:

a)定期进行代码审核并确保所有签入的代码都经过验证

b)另一种方法是在数据模型中强制执行此操作。为什么不在这个字段上使用DateTimeOffset属性并停止担心。