2016-09-09 4 views
2

ASP.NET MVC 5を使用してアプリケーションを作成しています。データベースに保存するすべてのdatetimeは、ローカルタイムゾーンからUTCタイムゾーンに変換する必要があります。Entity Frameworkは保存時にdatetimeフィールドを自動的にUTCに変換できますか?

リクエストサイクル中に最適な場所がどこにあるか不明です。

ViewModelルールを渡した後、各フィールドをコントローラでUTCに変換できます。しかし、私はこれがあまりにも多くのコード/ステップであると感じています。

エンティティフレームワークに、変更を保存する前に自動的にdatetimeをUTCに変換するルールを追加する方法はありますか?

この私はUTC

public static DateTime? ConvertToUTC(DateTime? val, TimeZoneInfo destinationTimeZone = null) 
{ 
     if (val != null) 
     { 
      var dateTimeToConvert = ConvertToDateTime(val); 

      if (destinationTimeZone == null) 
      { 
       if (ConfigurationManager.AppSettings["LocalTimeZone"] != null) 
       { 
        destinationTimeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["LocalTimeZone"]); 
       } 
       else 
       { 
        destinationTimeZone = TimeZoneInfo.FindSystemTimeZoneById(TimeZone.CurrentTimeZone.StandardName); 
       } 
      } 
      return TimeZoneInfo.ConvertTimeFromUtc(dateTimeToConvert, destinationTimeZone); 

     } 

     return null; 
} 
+0

最高の場所は、クライアントから行うことです。クライアントだけが自分がどのタイムゾーンを使用しているかを知っていて、クライアントが日付時刻をUTCまたはDateTimeOffsetタイプとして送信するのはクライアントの責任である必要があります。サーバー上で実行しないでください。その時点で、すべてのクライアントがサーバーと同じタイムゾーンで実行されていることを確認できない限り、遅すぎます(*イントラネットWebアプリケーションで動作する可能性があります)。同じことがdatetimeを送信し、UTCとしてクライアントに送信し、クライアントをロケールに変換させます。これをうまく処理するクライアントサイドライブラリがあります。 – Igor

+0

私はユーザーのローカルタイムゾーンをユーザープロファイルで知っています。すべてはそれから派生しています。 – Jaylen

+0

ユーザーは旅行しますか?ユーザーBobがニューヨークからL.Aに移動するとどうなりますか?そして、BobはプロパティとしてDateTimeを持つDBに何かをコミットするか、DateTimeプロパティを持つものを取得しますか? Bobは以前にタイムゾーン情報を更新しておく必要があります。多分、Bobが新しいタイムゾーンに移動する場合はうまくいくかもしれませんが、ボブが異なるタイムゾーンを頻繁に使う旅行者である場合、これは管理が難しくなります。 – Igor

答えて

1

に与える日時を変換します書いた方法は私が前に自動的にUTCに日時を変換ルールを追加することができますEntity Frameworkの中に方法はありさ変更を保存しますか?

DbContextで呼び出される前に、SaveChanges/SaveChangesAsyncメソッドをオーバーライドして変換を実行できます。

// on your DbContext type 

public override int SaveChanges(){ 
    DateTimeUtcHelper.SetDatesToUtc(this.ChangeTracker.Entries()); 
    return base.SaveChanges(); 
} 

class DateTimeUtcHelper{ 
    internal static void SetDatesToUtc(IEnumerable<DbEntityEntry> changes) { 
     foreach (var dbEntry in changes.Where(x => ChangesToTrackList.Contains(new[] {EntityState.Added, EntityState.Modified}))){ 
      foreach (var propertyName in dbEntry.CurrentValues.PropertyNames){ 

       // using reflection add logic to determine if its a DateTime or nullable DateTime 
       // && if its kind = DateTimeKind.Local or Unspecified 
       // and then convert set the Utc value 
       // and write it back to the entry using dbEntry.CurrentValues[propertyName] = utcvalue; 

      } 
     } 
    } 
} 

あなたはユーザー(つまりから来なかった変化に日時を変更しているインスタンスが存在しないことを確認するために、独自のロジックを追加する必要があります。デフォルトでは、あなたのマテリアライズド・日付時刻が持っていることを確認してくださいDateTimeKind.Utcフラグが設定されているか、ユーザーのために変更した場合は.Local)。


編集

DbContextはまた、あなたが渡すことができますので、おそらくのSaveChangesの過負荷がより適しだろう。それがで実行されていることをその要求コンテキストのユーザーのプロファイルにタイムゾーンにアクセスする必要がありますDIを使用している場合はORに、おそらく作成したDbContextに注入することができます。

+0

ChangesToTrackListが定義されていません。 – Talon

関連する問題