2

I have the following SQL table:

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()
)

So I set a default value for Created and set it to not null.

How should Entity Framework configuration be? Something like:

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

Do I need to add IsRequired? I am not sure if IsRequired means that EF should require a value for Created or if Created is required on the database.

Miguel Moura
  • 36,732
  • 85
  • 259
  • 481

2 Answers2

1

IsRequired would set the column to be NOT NULL in sql if the database were generated by EF.

Having a default value means if a value isn't specified when inserting a record, the default value will be used.

If you don't want to allow nulls in the column, the column should be NOT NULL and the entity property should be set IsRequired.

JC Ford
  • 6,946
  • 3
  • 25
  • 34
  • So when you have Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) IsRquired is also needed because it is NotNull ... And the same happens with HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed) if there is a default value defined and not null. Is this right? – Miguel Moura Mar 23 '15 at 17:29
  • 2
    `HasDatabaseGeneratedOption` will prevent EF from setting any value at all to the field, including null, so `IsRequired` is incompatible with it. – JC Ford Mar 23 '15 at 17:48
1

Well,EF doesn't have yet a good support for default values. Apparently this is something that EF 7 is going to have a better support due to the community has been requesting this some time ago.

I have already mapped your table using EF Power Tools and the configuration class that was generated was this:

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");
    }
}

As you can see the Created column was not mapped as required, and if you don't set that property, EF will going to throw an exception because that column will attempt to update with default(DateTime) wich is {1/1/0001 12:00:00 AM} and the type of that column is datetime (more details in this post).Even if you change the type of that column to datetime2, you are not going to have the behavior that you are expecting.

If you want a property with a default value, you could resolve that problem setting the property in the entity's contructor:

public class Post
{
   public int Id {get;set;}
   [Required]
   public DateTime Created{get;set;}
   public Post()
   {
      Created=DateTime.Now;
   }
}
Community
  • 1
  • 1
ocuenca
  • 38,548
  • 11
  • 89
  • 102