2015-11-03 2 views
8

Когда-нибудь при использовании Entity Framework Code Вначале соглашения по умолчанию не создают необходимый тип базы данных. Например, по умолчанию свойство типа System.DateTime создает столбец базы данных типа DateTime. Что делать, если вы хотите, чтобы у него был тип datetime2 (тип DateTime, который не имеет проблем с часовыми поясами и летнее время)?Код элемента Entity Framework Сначала: какой атрибут DataType для DateTime2?

Можно указать необходимый тип базы данных с помощью аннотаций данных с помощью DataTypeAtrribute. Один из конструкторов DataTypeAttribute принимает параметр DataType Enumeration. Таким образом, можно было бы указать, что-то вроде:

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

Тип DataType перечисление содержит много типов, однако он отсутствует значение для DateTime2.

Другим подходом будет использование Fluent API. Создание DateTime2 в методе DBContext.OnModelCreating:

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

DataTypeAttribute имеет second constructor that accepts a string. Эта строка определена как

Имя настраиваемого шаблона поля для связи с полем данных.

Так можно было бы предположить, что следующий будет достаточно, чтобы создать Datetime2:

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

Увы, это не работает. Созданная колонка по-прежнему имеет формат DateTime.

Вопрос: какую строку использовать в конструкторе для создания datetime2?

ответ

18

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

Колонка аннотаций является более искусны в определении атрибутов отображенной колонкой. Вы можете указать имя, тип данных или даже порядок, в котором столбец отображается в таблице. [...] Не путайте атрибут TypeName столбца с DataType DataAnnotation. DataType - это аннотация, используемая для пользовательского интерфейса, и сначала игнорируется кодом.

Итак:

[Column(TypeName="datetime2")] 
4

Для тех, кто еще заинтересован в том, чтобы определить типы столбцов для свойств. В DbContext.OnModelCreating вы можете определить, что каждое значение какого-либо типа должно иметь некоторый тип базы данных.

Если вы сделаете это, вам не нужно писать атрибуты и свободно API для каждого DateTime. Легче быть последовательным, и пусть все DateTime имеют одинаковый тип столбца. Точно так же вы можете дать все десятичные знаки той же точности, даже если десятичные знаки будут добавлены в будущем.

Предположим, вы хотите определить, что каждый System.DateTime должен иметь тип столбца DateTime2; каждый System.Decimal должен иметь тип столбца с заданной точностью.В DbContext можно было бы написать:

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