实体框架代码首次日期字段创建
Posted
技术标签:
【中文标题】实体框架代码首次日期字段创建【英文标题】:Entity Framework Code First Date field creation 【发布时间】:2011-08-05 05:15:09 【问题描述】:我正在使用 Entity Framework Code First 方法来创建我的数据库表。以下代码
在数据库中创建一个DATETIME
列,但我想创建一个DATE
列。
[DataType(DataType.Date)]
[DisplayFormatAttribute(ApplyFormatInEditMode = true, DataFormatString = "0:d")]
public DateTime ReportDate get; set;
如何在创建表的过程中创建DATE
类型的列?
【问题讨论】:
【参考方案1】:尝试使用System.ComponentModel.DataAnnotations
中的ColumnAttribute
(在EntityFramework.dll中定义):
[Column(TypeName="Date")]
public DateTime ReportDate get; set;
【讨论】:
如果您指向不支持日期的数据库,您可能会收到错误,Sequence contains no matching element
。 SQL Server 2014 可以。
在 EF6 中你需要using System.ComponentModel.DataAnnotations.Schema;
【参考方案2】:
大卫罗斯的答案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 基类来完成这项工作。
【讨论】:
【参考方案3】:我使用以下
[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
【参考方案4】:
我发现这在 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;
【讨论】:
非常棒的解决方案!我想添加的一件事是完全清楚的,为了使用它,您需要在 date 属性上添加属性,例如[DataType(DataType.Date)] public DateTime IssueDate get;放; @StephenLautier 是的,如果您希望仅将其用于特定的 DateTime 属性,则必须添加该属性。在我添加的代码中,我展示了您还可以将一般规则应用于所有 DateTime 类型,然后将更具体的规则应用于具有 DataType(DataType.Date) 装饰的那些。希望这可以消除任何困惑。 很好的解决方案,但 EF 确实提供了一个基类来为您完成这项工作 - 有关详细信息,请参阅我的解决方案。 @Richard 我对您的解决方案投了赞成票,因为您是正确的。我创建解决方案的原因是因为 EF 默认 DateTime 属性在 SQL Server 中使用 datetime 数据类型,而不是与 .NET DateTime 属性兼容的 datetime2 数据类型。值得庆幸的是,EF 核心现在已经解决了这个问题。【参考方案5】:如果你不想用属性来装饰你的类,你可以在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
【讨论】:
【参考方案6】:除了使用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());
【讨论】:
这应该内置在 EF 中。感谢分享! 不幸的是,从 EF6 开始,这已被弃用并且不再有效。 EF6 确实提供了一种新的方法 - 有关详细信息,请参阅我的解决方案。【参考方案7】:这只是@LadislavMrnka 在这个问题上对most up-voted answer 的增强
如果您有很多 Date
列,那么您可以创建自定义属性,然后在需要时使用它,这将在实体类中生成更简洁的代码
public class DateColumnAttribute : ColumnAttribute
public DateColumnAttribute()
TypeName = "date";
用法
[DateColumn]
public DateTime DateProperty get; set;
【讨论】:
【参考方案8】:这适用于 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;
见column data types。
【讨论】:
【参考方案9】:它使用的最佳方式
[DataType(DataType.Date)]
public DateTime ReportDate get; set;
但您必须使用 EntityFramework v 6.1.1
【讨论】:
以上是关于实体框架代码首次日期字段创建的主要内容,如果未能解决你的问题,请参考以下文章