实体框架将DateTimeOffset映射到SQL Server DateTime

Car*_*los 8 mapping entity-framework ef-code-first

有没有办法将DateTimeOffset属性映射到SQL Server datetime列,假设您不能更改任何一方,这意味着属性和列必须保留这些日期类型?

我知道最简单的方法是让它们匹配,但想知道是否有办法解决这个问题.我正在研究自定义映射,但似乎我必须自己映射所有列,而不仅仅是DateTimeOffset属性.

我试过了:

modelBuilder.Entity<Customer>().Property(c => c.LastModifiedOn).HasColumnType("datetime");
Run Code Online (Sandbox Code Playgroud)

但那引发了Member Mapping specified is not valid错误.

我希望能够将UtcDateTime DateTimeOffset属性值放在数据库中,并且当读取时具有DateTimeOffsetUTC(即偏移量为零).

谢谢.

Lad*_*nka 16

DateTimeOffset.NET类中的编号将映射到DateTimeOffsetSQL类型.您无法直接更改此行为,因为EF不提供简单的类型转换/映射.如果你想存储它,因为DateTime你必须破解它.

首先使用技巧定义Customer类,将私有属性暴露给@ cincura.net在此帖子中引用的映射:

public class Customer
{
    public static class CustomerExpressions
    {
        public static readonly Expression<Func<Customer, DateTime>> LastModifiedOn = c => c.LastModifiedOnInternal;
    }

    // Other properties

    public DateTimeOffset LastModifiedOn
    {
        get { return new DateTimeOffset(LastModifiedOnInternal); }
        set { LastModifiedOnInternal = value.DateTime; }
    }

    private DateTime LastModifiedOnInternal { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在您有两个属性 - 一个是私有的,并且持有DataTime您要保留到数据库的属性,另一个是DateTimeOffset您的应用程序的公开公开.在您的上下文中定义它:

public class Context : DbContext
{
    public DbSet<Customer> Customers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>().Ignore(c => c.LastModifiedOn);
        modelBuilder.Entity<Customer>().Property(Customer.CustomerExpressions.LastModifiedOn).HasColumnName("LastModifiedOn");
    }
}
Run Code Online (Sandbox Code Playgroud)

无论如何你不DateTime直接使用并将其存储在UTC中?

  • 避免使用EF的DateTime的一个原因是值不会往返:所有值都使用DateTimeKind.Unspecified加载.无法告诉EF它应该默认为UTC.当然有黑客可以解决它,但它们很难看,有些可能会损害性能(使用ObjectContext事件). (6认同)