【问题标题】:IsRequired applied to column with default valueIsRequired 应用于具有默认值的列
【发布时间】:2015-03-23 17:13:17
【问题描述】:

我有以下 SQL 表:

create table dbo.Post (
  Id int identity not null,
  Content nvarchar (max) not null,
  Title nvarchar (200) not null,
  Created datetime not null
    constraint DF_Post_Created default getutcdate()
)

所以我为 Created 设置了一个默认值并将其设置为不为空。

Entity Framework 应该如何配置?比如:

Property(x => x.Created).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);

我需要添加 IsRequired 吗?我不确定 IsRequired 是否意味着 EF 应该需要 Created 的值,或者数据库是否需要 Created。

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    如果数据库是由 EF 生成的,IsRequired 将在 sql 中将列设置为NOT NULL。

    有默认值意味着如果没有指定值插入记录时,将使用默认值。

    如果您不想在列中允许空值,则该列应为 NOT NULL,并且应将实体属性设置为 IsRequired。

    【讨论】:

    • 所以当你有 Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) IsRquired 也是需要的,因为它是 NotNull ... HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed) 也是如此如果定义了默认值且不为空。对吗?
    • HasDatabaseGeneratedOption 将阻止 EF 为该字段设置任何值,包括 null,因此 IsRequired 与它不兼容。
    【解决方案2】:

    嗯,EF 还没有很好地支持默认值。显然这是 EF 7 将得到更好的支持,因为社区已经 requesting 前一段时间了。

    我已经使用EF Power Tools 映射了您的表,并且生成的配置类是这样的:

    public class PostMap : EntityTypeConfiguration<Post>
    {
        public PostMap()
        {
            // Primary Key
            this.HasKey(t => t.Id);
    
            // Properties
            this.Property(t => t.Content)
                .IsRequired();
    
            this.Property(t => t.Title)
                .IsRequired()
                .HasMaxLength(200);
    
            // Table & Column Mappings
            this.ToTable("Posts");
            this.Property(t => t.Id).HasColumnName("Id");
            this.Property(t => t.Content).HasColumnName("Content");
            this.Property(t => t.Title).HasColumnName("Title");
            this.Property(t => t.Created).HasColumnName("Created");
        }
    }
    

    如您所见,Created 列未按要求映射,如果您未设置该属性,EF 将抛出异常,因为该列将尝试使用 default(DateTime) 更新,即 @987654328 @ 并且该列的类型是 datetime(更多详细信息在此 post 中)。即使您将该列的类型更改为 datetime2,您也不会有您所期望的行为。

    如果您想要一个具有默认值的属性,您可以在实体的构造函数中设置属性来解决该问题:

    public class Post
    {
       public int Id {get;set;}
       [Required]
       public DateTime Created{get;set;}
       public Post()
       {
          Created=DateTime.Now;
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多