Entity Framework Отображение DateTimeOffset на SQL Server DateTime - PullRequest
7 голосов
/ 22 февраля 2012

Есть ли способ сопоставить свойство DateTimeOffset со столбцом SQL Server datetime, предполагая, что вы не можете изменить ни одну из сторон, что означает, что свойство и столбец должны соответствовать этим типам даты?

Я знаю, что проще всего сделать так, чтобы они совпадали, но я хочу знать, есть ли способ обойти это. Я изучал пользовательские сопоставления, но казалось, что мне нужно было сопоставить все столбцы самостоятельно, а не только свойство DateTimeOffset.

Я пытался:

modelBuilder.Entity<Customer>().Property(c => c.LastModifiedOn).HasColumnType("datetime");

Но это привело к ошибке Member Mapping specified is not valid.

Я надеялся, что смогу поместить значение свойства UtcDateTime DateTimeOffset в БД, и при чтении значение DateTimeOffset будет в UTC (т.е. смещение равно нулю).

Спасибо.

1 Ответ

15 голосов
/ 23 февраля 2012

Нет. DateTimeOffset в классе .NET будет соответствовать DateTimeOffset типу SQL. Вы не можете изменить это поведение напрямую, потому что 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; }
}

Теперь у вас есть два свойства - одно из них закрытое и содержит 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");
    }
}

В любом случае, почему вы не используете DateTime напрямую и не храните его в UTC?

...