实体框架DateTime和UTC [英] Entity Framework DateTime and UTC

查看:123
本文介绍了实体框架DateTime和UTC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是有可能有实体框架(我用的是code首先引桥目前CTP5)存储中的所有日期时间值作为UTC在数据库?

还是有可能在映射指定它,例如,在这一个用于LAST_LOGIN列的方式:

  modelBuilder.Entity<使用者方式>()房产(X => x.Id).HasColumnName(ID);
modelBuilder.Entity<使用者>()房产(X => x.IsAdmin)。.HasColumnName(管理);
modelBuilder.Entity<使用者>()房产(X => x.IsEnabled)。.HasColumnName(已启用);
modelBuilder.Entity<使用者>()房产(X => x.PasswordHash)。.HasColumnName(password_hash);
modelBuilder.Entity<使用者>()房产(X => x.LastLogin)。.HasColumnName(LAST_LOGIN);


解决方案

下面是你可以考虑一种方法:

首先,定义此以下属性:

  [AttributeUsage(AttributeTargets.Property)
公共类DateTimeKindAttribute:属性
{
    私人只读DateTimeKind _kind;    公共DateTimeKindAttribute(DateTimeKind的那种)
    {
        _kind =样;
    }    公共DateTimeKind种类
    {
        {返回_kind; }
    }    公共静态无效的申请(对象实体)
    {
        如果(实体== NULL)
            返回;        VAR性能= entity.GetType()的GetProperties()
            。凡(X => x.PropertyType == typeof运算(DATETIME)|| x.PropertyType == typeof运算(日期时间)?);        的foreach(在性能VAR属性)
        {
            VAR ATTR = property.GetCustomAttribute< D​​ateTimeKindAttribute>();
            如果(ATTR == NULL)
                继续;            VAR DT = property.PropertyType == typeof运算(日期时间?)
                ? (日期时间?)property.GetValue(实体)
                (DATETIME)property.GetValue(实体);            如果(DT == NULL)
                继续;            property.SetValue(实体,DateTime.SpecifyKind(dt.Value,attr.Kind));
        }
    }
}

现在钩该属性到您的EF方面:

 公共类MyContext:的DbContext
{
    公共DbSet<富> FOOS {搞定;组; }    公共MyContext()
    {
        ((IObjectContextAdapter)本).ObjectContext.ObjectMaterialized + =
            (发件人,E)=> DateTimeKindAttribute.Apply(e.Entity);
    }
}

现在任何的DateTime 的DateTime 属性,你可以应用此属性:

 公共类Foo
{
    公众诠释标识{搞定;组; }    [DateTimeKind(DateTimeKind.Utc)
    公众的DateTime酒吧{搞定;组; }
}

有了这个地方,只要实体框架从数据库加载一个实体​​,它将设置 DateTimeKind 您指定,如UTC。

注意保存时,这并不做任何事情。你还必须有正确地转换为UTC您尝试保存它之前的值。但是,它允许您设置检索时的那种,这使得它能够序列化为UTC,或转换为其他时区与的TimeZoneInfo

is it possible to have Entity Framework (I am using the Code First Approach with CTP5 currently) store all DateTime values as UTC in the database?

Or is there maybe a way to specify it in the mapping, for example in this one for the last_login column:

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");

解决方案

Here is one approach you might consider:

First, define this following attribute:

[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));
        }
    }
}

Now hook that attribute up to your EF context:

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

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

Now on any DateTime or DateTime? properties, you can apply this attribute:

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

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

With this in place, whenever Entity Framework loads an entity from the database, it will set the DateTimeKind that you specify, such as UTC.

Note that this doesn't do anything when saving. You'll still have to have the value properly converted to UTC before you try to save it. But it does allow you to set the kind when retrieving, which allows it to be serialized as UTC, or converted to other time zones with TimeZoneInfo.

这篇关于实体框架DateTime和UTC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆