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 がデータベースからエンティティを読み込むたびに、DateTimeKind
UTC などの指定したが設定されます。
保存時には何も行われないことに注意してください。保存する前に、値を適切に UTC に変換する必要があります。ただし、取得時に種類を設定できるため、UTC としてシリアル化したり、 を使用して他のタイムゾーンに変換したりできますTimeZoneInfo
。