Создание поля Entity Framework Code First Date - PullRequest
75 голосов
/ 14 апреля 2011

Я использую метод Entity Framework Code First для создания таблицы базы данных. Следующий код создает столбец DATETIME в базе данных, но я хочу создать столбец DATE.

[DataType(DataType.Date)]
[DisplayFormatAttribute(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
public DateTime ReportDate { get; set; }

Как создать столбец типа DATE при создании таблицы?

Ответы [ 8 ]

147 голосов
/ 14 апреля 2011

Попробуйте использовать ColumnAttribute из System.ComponentModel.DataAnnotations (определено в EntityFramework.dll):

[Column(TypeName="Date")]
public DateTime ReportDate { get; set; }
20 голосов
/ 19 марта 2015

EF6-версия ответа Дэвида Рота выглядит следующим образом:

public class DataTypePropertyAttributeConvention 
    : PrimitivePropertyAttributeConfigurationConvention<DataTypeAttribute>
{
    public override void Apply(ConventionPrimitivePropertyConfiguration configuration, 
        DataTypeAttribute attribute)
    {
        if (attribute.DataType == DataType.Date)
        {
            configuration.HasColumnType("Date");
        }
    }
}

Зарегистрируйте это, как и раньше:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Conventions.Add(new DataTypePropertyAttributeConvention());
}

Это имеет тот же результат, что и подход Тайлера Дюрдена, за исключением того, чтоиспользуя базовый класс EF для работы.

8 голосов
/ 30 июля 2014

Я нашел это работает в EF6 красиво.

Я создал соглашение для указания моих типов данных.Это соглашение изменяет тип данных DateTime по умолчанию при создании базы данных с datetime на datetime2.Затем он применяет более конкретное правило к любым свойствам, которые я украсил атрибутом DataType (DataType.Date).

public class DateConvention : Convention
{
    public DateConvention()
    {
        this.Properties<DateTime>()
            .Configure(c => c.HasColumnType("datetime2").HasPrecision(3));

        this.Properties<DateTime>()
            .Where(x => x.GetCustomAttributes(false).OfType<DataTypeAttribute>()
            .Any(a => a.DataType == DataType.Date))
            .Configure(c => c.HasColumnType("date"));
    }
}

Затем зарегистрируйте соглашение в вашем контексте:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    modelBuilder.Conventions.Add(new DateConvention());
    // Additional configuration....
}

Добавьте атрибут ко всем свойствам DateTime, для которых вы хотите использовать только дату:

public class Participant : EntityBase
{
    public int ID { get; set; }

    [Required]
    [Display(Name = "Given Name")]
    public string GivenName { get; set; }

    [Required]
    [Display(Name = "Surname")]
    public string Surname { get; set; }

    [DataType(DataType.Date)]
    [Display(Name = "Date of Birth")]
    public DateTime DateOfBirth { get; set; }
}
6 голосов
/ 11 декабря 2016

Я использую следующие

    [DataType(DataType.Time)]
    public TimeSpan StartTime { get; set; }

    [DataType(DataType.Time)]
    public TimeSpan EndTime { get; set; }

    [DataType(DataType.Date)]
    [Column(TypeName = "Date")]
    public DateTime StartDate { get; set; }

    [DataType(DataType.Date)]
    [Column(TypeName = "Date")]
    public DateTime EndDate { get; set; }

С Entity Framework 6 и SQL Server Express 2012 - 11.0.2100.60 (X64). Он отлично работает и генерирует типы столбцов времени / даты в SQL Server

4 голосов
/ 03 ноября 2016

Если вы предпочитаете не украшать свои классы атрибутами, вы можете установить это в DbContext OnModelCreating следующим образом:

public class DatabaseContext: DbContext
{
    // DbSet's

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // magic starts
        modelBuilder.Entity<YourEntity>()
                    .Property(e => e.ReportDate)
                    .HasColumnType("date");
        // magic ends

        // ... other bindings
    }
}
4 голосов
/ 21 марта 2013

Помимо использования ColumnAttribute вы также можете создать пользовательское соглашение об атрибутах для DataTypeAttribute:

public class DataTypePropertyAttributeConvention : AttributeConfigurationConvention<PropertyInfo, PrimitivePropertyConfiguration, DataTypeAttribute>
{
    public override void Apply(PropertyInfo memberInfo, PrimitivePropertyConfiguration configuration, DataTypeAttribute attribute)
    {
        if (attribute.DataType == DataType.Date)
        {
            configuration.ColumnType = "Date";
        }
    }
}

Просто зарегистрируйте соглашение в своем методе OnModelCreating:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Conventions.Add(new DataTypePropertyAttributeConvention());
}
3 голосов
/ 15 ноября 2017

Это просто улучшение для ответа с наибольшим количеством голосов @LadislavMrnka на этот вопрос

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

public class DateColumnAttribute : ColumnAttribute
{
    public DateColumnAttribute()
    {
        TypeName = "date";
    }
}

Использование

[DateColumn]
public DateTime DateProperty { get; set; }
0 голосов
/ 11 мая 2015

Лучший способ это использовать

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

но вы должны использовать EntityFramework v 6.1.1

...