我正在使用 Entity Framework Code First 方法来创建我的数据库表。以下代码在数据库中创建一个 DATETIME
列,但我想创建一个 DATE
列。
[DataType(DataType.Date)]
[DisplayFormatAttribute(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
public DateTime ReportDate { get; set; }
如何在创建表期间创建类型为 DATE
的列?
尝试使用 System.ComponentModel.DataAnnotations
中的 ColumnAttribute
(在 EntityFramework.dll 中定义):
[Column(TypeName="Date")]
public DateTime ReportDate { get; set; }
David Roth 回答的 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());
}
这与 Tyler Durden 的方法具有相同的结果,只是它使用 EF 基类来完成这项工作。
我使用以下
[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 中生成时间/日期列类型
@YakoobHammouri
不起作用。我必须按照您的建议同时使用注释 [DataType(DataType.Date)]
和 [Column(TypeName = "Date")]
。但是,此解决方案将日期格式创建为 yyyy-mm-dd
而不是 MM-dd-yyyy
我发现这在 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; }
}
如果您不想用属性装饰您的类,您可以在 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
}
}
除了使用 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());
}
这只是@LadislavMrnka 在这个问题上对 most up-voted answer 的增强
如果您有很多 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; }
}
它使用的最佳方式
[DataType(DataType.Date)]
public DateTime ReportDate { get; set; }
但您必须使用 EntityFramework v 6.1.1
Sequence contains no matching element
。 SQL Server 2014 可以。using System.ComponentModel.DataAnnotations.Schema;