2012-02-22 14 views
5

C'è un modo per mappare una proprietà DateTimeOffset a una colonna di SQL Server datetime, con l'ipotesi che non è possibile modificare entrambi i lati, il che significa che la proprietà e la colonna devono rimanere tali date tipi?Mappatura framework entità DateTimeOffset a SQL Server DateTime

So che il modo più semplice è farli corrispondere ma vogliono sapere se c'è un modo per ovviare a questo problema. Stavo analizzando le mappature personalizzate ma sembrava che dovessi mappare tutte le colonne da solo e non solo la proprietà DateTimeOffset.

ho provato:

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

Ma che ha gettato l'errore Member Mapping specified is not valid.

Speravo di essere in grado di inserire il valore di proprietà UtcDateTime DateTimeOffset nel db e durante la lettura il numero DateTimeOffset è in UTC (ovvero un offset di zero).

Grazie.

risposta

12

No. DateTimeOffset nella classe .NET verrà mappato al tipo di SQL DateTimeOffset. Non è possibile modificare questo comportamento direttamente perché EF non fornisce conversioni/mapping di tipo semplice. Se vuoi memorizzarlo come DateTime devi hackerarlo.

prima definire classe Customer con trucco per esporre la proprietà privata a cui fa riferimento la mappatura @ cincura.net in this post:

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

Ora avete due proprietà - uno è privato e tiene DataTime quale si vuole persistere di database e uno è pubblico esponendo DateTimeOffset per la vostra applicazione. Definire nel vostro contesto:

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

In ogni caso il motivo per cui non si usa DateTime direttamente e conservarla in UTC?

+0

Grazie per la risposta. Dobbiamo lavorare con più fusi orari e fare l'aritmetica con DateTimeOffset è più facile che dover convertire tutto in UTC prima di fare qualsiasi aritmetica con i tempi. – Carlos

+4

Un motivo per evitare DateTime con EF è che i valori non vengono arrotondati: tutti i valori vengono caricati con DateTimeKind.Unspecified. Non c'è modo di dire a EF che dovrebbe essere impostato su UTC. Certo, ci sono degli hack per sistemarlo, ma sono brutti e alcuni potrebbero danneggiare le prestazioni (usando gli eventi ObjectContext). –

+0

@ SørenBoisen - Nella mia migrazione durante la creazione di tabelle, aggiungo 'defaultValueSql:" GETUTCDATE() "' – Suamere

Problemi correlati