Mickael Caruso
Mickael Caruso

Reputation: 9441

Entity Framework Default DateTime Annotation Does Not Migrate

I want to create a DateTime field so that it will have a default GETDATE() once it gets to the database. So I did this:

 public class Specialty
 {
     [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
     public DateTime? CreatedDate { get; set; }

     // other properties not shown for brevity.
 }

So I ran Add-Migration in the PM> console. It resulted in this (not all lines are shown) in the Up function:

AddColumn("dbo.Specialty", "CreatedDate", c => c.DateTime());

I understand that nullable of c.DateTime(...) is true by default, so I understand why it's not specified. BUT where is defaultValueSql: "GETDATE()"?

I know I can put it in manually, but that seems to defeat the purpose of Add-Migration and makes [DatabaseGenerated(DatabaseGeneratedOption.Computed)] useless. I know for a fact that defaultValueSql's default is not "GETDATE()" because it doesn't show up when I look at column properties in SQL Management Studio.

What's missing? Does the name "CreatedDate" violate an EF convention, then? Is there another library that I should have referenced besides System.ComponentModel.DataAnnotations.Schema?

Upvotes: 8

Views: 5616

Answers (2)

demoncodemonkey
demoncodemonkey

Reputation: 11957

I ended up inheriting all entities from a base class, following these instructions.

This means making a custom migration class for the CreatedDate and UpdatedDate column, and it works perfectly with minimal effort.

Upvotes: 0

Colin
Colin

Reputation: 22595

[DatabaseGenerated(DatabaseGeneratedOption.Computed)] is not useless, it tells the Entity Framework that the column is required in the database but is computed by the database. So it knows that it should create the column in a migration and it knows that it should not try to update its value nor insert a value.

What is missing is that you have to add the computation to the database column. And you do that by modifying the migration:

        AddColumn("dbo.Specialty", 
                  "CreatedDate", 
                  c => c.DateTime(defaultValueSql: "GETDATE()"));

There is currently no way to specify the sql in a data annotation, and I suspect that there never will be because the sql could be database specific, and is therefore best kept within a migration rather than being allowed to leak into the model definition

Upvotes: 12

Related Questions