【问题标题】: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 类型的列?

【问题讨论】:

    标签: c# entity-framework entity-framework-4.1 code-first sqldatatypes


    【解决方案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】:

      如果你不想用属性来装饰你的类,你可以在DbContextOnModelCreating中这样设置:

      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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-01-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多