簡體   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