Entity Framework Code İlk Tarih alanı oluşturma


83

Veritabanı tablomu oluşturmak için Entity Framework Code First yöntemini kullanıyorum. Aşağıdaki kod DATETIME, veritabanında bir sütun oluşturuyor , ancak bir DATEsütun oluşturmak istiyorum .

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

DATETablo oluşturma sırasında nasıl sütun türü oluşturabilirim ?

Yanıtlar:


22

David Roth'un cevabının EF6 versiyonu aşağıdaki gibidir:

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

Bunu daha önce olduğu gibi kaydedin:

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

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

Bu, iş için EF temel sınıfı kullanması dışında Tyler Durden'ın yaklaşımıyla aynı sonuca sahiptir.


165

Kullanmayı deneyin ColumnAttributeden System.ComponentModel.DataAnnotations(EntityFramework.dll tanımlanan):

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

1
Sequence contains no matching elementTarihi desteklemeyen bir DB'yi gösteriyorsanız hata alabilirsiniz . SQL Server 2014 yapar.
Jess

8
EF6'da ihtiyacınız varusing System.ComponentModel.DataAnnotations.Schema;
JohnnyHK

11

Ben aşağıdakileri kullanıyorum

    [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 ve SQL Server Express 2012 - 11.0.2100.60 (X64) ile. Kusursuz çalışır ve sql sunucusunda saat / tarih sütun türleri oluşturur


Çözümünüz işe yaradı. @YakoobHammouriişe yaramadı. Her iki ek açıklamaları kullanmak zorunda kaldı [DataType(DataType.Date)]ve [Column(TypeName = "Date")]gibi önerdi. Bununla birlikte, bu çözümyyyy-mm-ddMM-dd-yyyy
nam

9

Bu işe yarıyor EF6'da güzel buldum.

Veri türlerimi belirlemek için bir kural oluşturdum. Bu kural, veritabanı oluşturmadaki varsayılan DateTime veri türünü datetime'dan datetime2'ye değiştirir. Daha sonra DataType (DataType.Date) özniteliğiyle dekore ettiğim tüm özelliklere daha özel bir kural uygular.

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

Ardından, kendi bağlamınıza göre kongre kaydedin:

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

Özniteliği yalnızca tarih olmasını istediğiniz herhangi bir DateTime özelliğine ekleyin:

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

1
Gerçekten harika bir çözüm! Tamamen açık olmak istediğim bir şey, bunu kullanmak için özniteliği date özelliğine eklemeniz gerektiğidir, örneğin [DataType (DataType.Date)] public DateTime IssueDate {get; Ayarlamak; }
Stephen Lautier

@StephenLautier evet, bunu yalnızca belirli DateTime özellikleri için kullanabilmek istiyorsanız, niteliği eklemelisiniz. Eklediğim kodda, tüm DateTime tiplerinize genel bir kural ve ardından DataType (DataType.Date) dekorasyonuna sahip olanlara daha spesifik bir kural uygulayabileceğinizi gösteriyorum. Umarım bu herhangi bir karışıklığı giderir.
Tyler Durden

1
İyi çözüm, ancak EF bu işi sizin için yapmak için bir temel sınıf sağlar - ayrıntılar için çözümüme bakın.
Richard

@Richard çözümünüze oy verdim, çünkü haklısınız. Yine de çözümümü oluşturmamın nedeni, EF'nin DateTime özelliklerinin .NET DateTime özelliğiyle uyumlu datetime2 veri türünü değil SQL Server'da datetime veri türünü kullanmasını öntanımlı tutmasıydı. Neyse ki EF çekirdeği bu sorunu şimdi çözdü.
Tyler Durden

5

Sınıflarınızı niteliklerle dekore etmemeyi tercih ediyorsanız, bunu DbContext's' da şu şekilde ayarlayabilirsiniz 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

Kullanmanın yanı sıra, ColumnAttributeaşağıdakiler için özel bir öznitelik kuralı da oluşturabilirsiniz 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";
        }
    }
}

Kuralı OnModelCreating yönteminize kaydetmeniz yeterlidir:

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

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

Bu, EF'te yerleşik olmalıdır. Paylaşım için teşekkürler!
tugberk

Ne yazık ki bu, EF6 itibariyle kullanımdan kaldırılmıştır ve artık geçerli değildir.
Tyler Durden

1
EF6 bunu yapmanın yeni bir yolunu sağladı - ayrıntılar için çözümüme bakın.
Richard

3

Bu, @LadislavMrnka'nın bu soruya en çok oy veren yanıtı için yapılan bir geliştirmedir.

Çok sayıda Datesütununuz varsa, özel öznitelik oluşturabilir ve istediğiniz zaman kullanabilirsiniz, bu Entity sınıflarında daha temiz kod üretecektir.

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

Kullanım

[DateColumn]
public DateTime DateProperty { get; set; }

-3

Kullanmanın En İyi Yolu

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

ancak EntityFramework v 6.1.1 kullanmanız gerekir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.