2015-11-03 15 views
8

A volte quando si utilizza Entity Framework Code First, le convenzioni di default non creano il tipo di database desiderato. Ad esempio, per impostazione predefinita una proprietà di tipo System.DateTime crea una colonna del database di tipo DateTime. Che cosa fare se si desidera che abbia un tipo di datetime2 (il tipo DateTime che non ha problemi con i fusi orari e l'ora legale)?Codice quadro entità Primo: quale attributo DataType per DateTime2?

È possibile specificare il tipo di database richiesto con Annotazioni dati utilizzando DataTypeAtrribute. Uno dei costruttori di DataTypeAttribute accetta un parametro DataType Enumeration. Così si potrebbe specificare qualcosa di simile:

[DataType(DataType.DateTime)] 
public DateTime DateOfBirth {get; set;} 

Il tipo di tipo di dati di enumerazione contiene un sacco di tipi, tuttavia manca un valore per DateTime2.

Un altro approccio sarebbe l'utilizzo dell'API Fluent. Creare un metodo di DateTime2 in DBContext.OnModelCreating:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Student>().Property(p => p.BirthDate) 
     .HasColumnType("datetime2"); 
} 

Il DataTypeAttribute ha un second constructor that accepts a string. Questa stringa è definita come

Il nome del modello di campo personalizzato da associare al campo dati.

Così si potrebbe supporre che il seguente sarebbe sufficiente a creare un datetime2:

[DataType("datetime2")] 
public DateTime DateOfBirth {get; set;} 

Ahimè, questo non funziona. La colonna creata ha ancora il formato DateTime.

Domanda: quale stringa da utilizzare nel costruttore per creare un datetime2?

risposta

18

The DataType attribute is not used for column type mapping for Code First:

L'annotazione colonna è una più abile nello specificare gli attributi di una colonna mappata. È possibile specificare un nome, un tipo di dati o persino l'ordine in cui una colonna appare nella tabella. [...] Non confondere l'attributo TypeName di Column con DataType DataAnnotation. DataType è un'annotazione utilizzata per l'interfaccia utente e viene ignorata dal codice.

Quindi:

[Column(TypeName="datetime2")] 
4

Per chi ancora interessato a come definire tipi di colonna per le proprietà. In DbContext.OnModelCreating puoi definire che ogni valore di qualche tipo dovrebbe avere qualche tipo di database.

Se si esegue questa operazione, non è necessario scrivere attributi o API fluente per ogni DateTime. È più semplice essere coerenti e lasciare che tutti i DateTime abbiano lo stesso tipo di colonna. Allo stesso modo puoi dare a tutti i decimali la stessa precisione, anche se in futuro verranno aggiunti i decimali.

Si supponga di voler definire che ogni System.DateTime deve avere il tipo di colonna DateTime2; ogni System.Decimal dovrebbe avere un tipo di colonna con una precisione specificata.In DbContext dovresti scrivere:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    // every property of type DateTime should have a column type of "datetime2": 
    modelBuilder.Property<DateTime>() 
     .Configure(property => property.HasColumnType("datetime2"); 
    // every property of type decimal should have a precision of 19 
    // and a scale of 8: 
    modelBuilder.Property<decimal>() 
     .Configure(property => property.HasPrecision(19, 8); 
}