C# 实体框架代码第一个日期字段创建

C# 实体框架代码第一个日期字段创建,c#,entity-framework,entity-framework-4.1,code-first,sqldatatypes,C#,Entity Framework,Entity Framework 4.1,Code First,Sqldatatypes,我使用实体框架代码优先方法创建数据库表。下面的代码 在数据库中创建一个DATETIME列,但我想创建一个DATE列 [DataType(DataType.Date)] [DisplayFormatAttribute(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")] public DateTime ReportDate { get; set; } 在创建表的过程中,如何创建类型为DATE的列?尝试从System.Componen

我使用实体框架代码优先方法创建数据库表。下面的代码 在数据库中创建一个
DATETIME
列,但我想创建一个
DATE

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

在创建表的过程中,如何创建类型为
DATE
的列?

尝试从
System.ComponentModel.DataAnnotations
(在EntityFramework.dll中定义)使用
ColumnAttribute


除了使用
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";
        }
    }
}

我发现这在EF6中非常有效

我创建了一个用于指定数据类型的约定。此约定将数据库创建中的默认日期时间数据类型从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"));
    }
}

David Roth回答的EF6版本如下:

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

这与Tyler Durden的方法具有相同的结果,只是它使用EF基类进行作业。

使用

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

但是您必须使用EntityFramework v6.1.1

如果您不想用属性装饰类,可以在
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
    }
}
公共类数据库上下文:DbContext
{
//数据库集
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
//魔术开始了
modelBuilder.Entity()
.属性(e=>e.ReportDate)
.HasColumnType(“日期”);
//神奇的结局
//…其他绑定
}
}
我使用以下方法

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

使用实体框架6和SQL Server Express 2012-11.0.2100.60(X64)
它工作正常,在SQL server中生成时间/日期列类型

这只是@LadislavMrnka在这个问题上的一个增强功能

如果您有很多
Date
列,那么您可以创建自定义属性,然后在需要时使用它,这将在实体类中生成更多干净的代码

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

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

这对EF Core 5+PostgreSQL有效:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

public class Birthday
{
    [Key]
    public int Id { get; set; }
    
    [Column(TypeName = "date")]
    public DateTime DateOfBirth { get; set; }
}


请参阅。

这应该内置到EF中。谢谢分享!不幸的是,从EF6开始,它就被弃用了,不再有效。EF6确实提供了一种新的方法来实现这一点-有关详细信息,请参阅我的解决方案。真是一个很棒的解决方案!有一件事我想补充清楚,为了使用它,您需要在date属性上添加属性,例如[DataType(DataType.date)]public DateTime IssueDate{get;set;}@StephenLautier yes如果您希望能够将此属性仅用于特定的DateTime属性,则必须添加该属性。在我添加的代码中,我展示了您还可以对所有DateTime类型应用一个通用规则,然后对带有数据类型(DataType.Date)装饰的类型应用一个更具体的规则。希望这能消除任何困惑。这是一个很好的解决方案,但EF确实为您提供了一个基类来完成这项工作-有关详细信息,请参阅我的解决方案。@Richard我对您的解决方案投了赞成票,因为您是对的。但我创建解决方案的原因是,EF默认DateTime属性在SQL Server中使用DateTime数据类型,而不是与.NET DateTime属性兼容的datetime2数据类型。谢天谢地,EF core现在已经解决了这个问题。如果您指向不支持日期的数据库,则可能会出现错误,
序列不包含匹配元素。SQL Server 2014确实如此。在EF6中,您需要
使用System.ComponentModel.DataAnnotations.Schema您的解决方案有效
@YakoobHammouri
的不起作用。我必须按照您的建议使用注释
[DataType(DataType.Date)]
[Column(TypeName=“Date”)]
。但是,此解决方案将日期格式创建为
yyyy-mm-dd
,而不是
mm-dd-yyyy
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
    }
}
[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; }
public class DateColumnAttribute : ColumnAttribute
{
    public DateColumnAttribute()
    {
        TypeName = "date";
    }
}
[DateColumn]
public DateTime DateProperty { get; set; }
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

public class Birthday
{
    [Key]
    public int Id { get; set; }
    
    [Column(TypeName = "date")]
    public DateTime DateOfBirth { get; set; }
}