它是well known在數據庫中,您應該以通用時間座標存儲日期。當寫入數據庫時使用DateTime.Now時的Incercept
我正在尋找一種方法來了解開發人員在寫入數據庫時是否濫用了DateTime.Now。
我們使用Sql Server 2008,使用EF4或nHibernate 3.0。
如果在Sql Server或NH/EF中包含時區信息的低層圖層,是否可以攔截日期時間值?
它是well known在數據庫中,您應該以通用時間座標存儲日期。當寫入數據庫時使用DateTime.Now時的Incercept
我正在尋找一種方法來了解開發人員在寫入數據庫時是否濫用了DateTime.Now。
我們使用Sql Server 2008,使用EF4或nHibernate 3.0。
如果在Sql Server或NH/EF中包含時區信息的低層圖層,是否可以攔截日期時間值?
您可以添加以下事件偵聽器:
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*/ }
}
(這是完全未經測試,可能會失敗,並從數據庫中檢索到的值用作啓動Poing的)
您可以在您的數據庫中編寫一個觸發器,用於記錄(或執行其他操作),當您期望在其附近的日期時間現在不在UTC附近時。
您可以將EF或NHibernate圖層的默認日期字段設置爲UTC現在,所以開發人員無需設置它們。
可能更好,您可以搜索DateTime.Now的代碼並查看使用情況。
我覺得在NHibernate中,你可以使用攔截器類來覆蓋OnSave上的OnLoad等基本方法。您可以嘗試攔截屬性類型並在插入數據庫之前管理您的日期。
看這裏:
http://knol.google.com/k/fabio-maulo/nhibernate-chapter-11-interceptors-and/1nr4enxv3dpeq/14#
以處置不良數據的關鍵是在儘可能早的時間內消除它。當你到達數據庫層的時候,做任何有用的事情都太遲了。
在運行時檢測SQL查詢中DateTime.Now
的使用可能不太可能。你最好通過你的代碼,並消除DateTime.Now
的所有用途。到處。設置一個編碼標準,使整個程序中的所有日期和時間都以UTC表示,除非必須在本地時間或其他時區輸出。這將是一個更好的長期解決問題的辦法。
不可能嗎?我們在這裏不使用這個詞。 – 2011-06-05 02:24:49
拋開日期是否應該存儲在UTC中的爭論,在代碼中檢查這些類型的東西的地方是在構建過程中,或者使用預先提交的鉤子失敗。
後者將只允許開發人員提交符合標準的代碼。在數據庫層執行它太晚了,IMO。
你不應該被引入代碼對您的開發人員編碼風格執行一條規則。您不必要地在應用程序中引入開銷。有很多方法可以解決這個問題:
一)有固定的代碼審查,並確保在驗證
二)其他方式檢查了所有的代碼是在你的數據模型來執行這一點。爲什麼不使用此字段上的DateTimeOffset屬性並停止擔心。
你的「衆所周知」事實本身有點主觀。雖然世界時間可能是一個很好的*默認*,有時候本地時間更方便和更合適。 – 2011-06-03 18:01:12
不,使用UTC存儲時間並不總是正確的。例如,公共汽車或火車時間表在UTC中沒有意義,但應在當地時間存儲。這同樣適用於約會。 – mnemosyn 2011-06-03 18:01:18
有關UTC與當地時間的深入討論,另請參閱http://stackoverflow.com/questions/2580478/storing-date-times-as-utc-in-database。請記住,日期時間不包含實際的時區信息,但僅包含一個標記,表示「Local,Utc」或「Unspecified」。 – mnemosyn 2011-06-03 18:08:30