Entity Framework DateTime と UTC 質問する

Entity Framework DateTime と UTC 質問する

Entity Framework (現在、CTP5 で Code First Approach を使用しています) を使用して、すべての DateTime 値を UTC としてデータベースに保存することは可能ですか?

または、マッピングで指定する方法があるでしょうか。たとえば、last_login 列の場合は次のようになります。

modelBuilder.Entity<User>().Property(x => x.Id).HasColumnName("id");
modelBuilder.Entity<User>().Property(x => x.IsAdmin).HasColumnName("admin");
modelBuilder.Entity<User>().Property(x => x.IsEnabled).HasColumnName("enabled");
modelBuilder.Entity<User>().Property(x => x.PasswordHash).HasColumnName("password_hash");
modelBuilder.Entity<User>().Property(x => x.LastLogin).HasColumnName("last_login");

ベストアンサー1

検討できるアプローチの 1 つを以下に示します。

まず、次の属性を定義します。

[AttributeUsage(AttributeTargets.Property)]
public class DateTimeKindAttribute : Attribute
{
    private readonly DateTimeKind _kind;

    public DateTimeKindAttribute(DateTimeKind kind)
    {
        _kind = kind;
    }

    public DateTimeKind Kind
    {
        get { return _kind; }
    }

    public static void Apply(object entity)
    {
        if (entity == null)
            return;

        var properties = entity.GetType().GetProperties()
            .Where(x => x.PropertyType == typeof(DateTime) || x.PropertyType == typeof(DateTime?));

        foreach (var property in properties)
        {
            var attr = property.GetCustomAttribute<DateTimeKindAttribute>();
            if (attr == null)
                continue;

            var dt = property.PropertyType == typeof(DateTime?)
                ? (DateTime?) property.GetValue(entity)
                : (DateTime) property.GetValue(entity);

            if (dt == null)
                continue;

            property.SetValue(entity, DateTime.SpecifyKind(dt.Value, attr.Kind));
        }
    }
}

次に、その属性を EF コンテキストに接続します。

public class MyContext : DbContext
{
    public DbSet<Foo> Foos { get; set; }

    public MyContext()
    {
        ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized +=
            (sender, e) => DateTimeKindAttribute.Apply(e.Entity);
    }
}

DateTimeこれで、任意のプロパティまたはプロパティにDateTime?、この属性を適用できます。

public class Foo
{
    public int Id { get; set; }

    [DateTimeKind(DateTimeKind.Utc)]
    public DateTime Bar { get; set; }
}

これを設定すると、Entity Framework がデータベースからエンティティを読み込むたびに、DateTimeKindUTC などの指定したが設定されます。

保存時には何も行われないことに注意してください。保存する前に、値を適切に UTC に変換する必要があります。ただし、取得時に種類を設定できるため、UTC としてシリアル化したり、 を使用して他のタイムゾーンに変換したりできますTimeZoneInfo

おすすめ記事