well known在数据库中,您应该以通用时间坐标存储日期。
我正在寻找一种方法来了解开发人员何时在写入数据库时误用DateTime.Now。
我们正在使用Sql Server 2008,使用EF4或nHibernate 3.0。
当它包含低级别层的时区信息时,是否可以拦截日期时间的值,例如在Sql Server或NH / EF中?
答案 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属性并停止担心。