SQL column default value with Entity Framework

.net entity-framework entity-framework-6

Question

I am trying to use Code-First EF6 with default SQL values.

For example, I have a "CreatedDate" column/property not null with a default in SQL of "getdate()"

How do I represent this in my code Model? Currently I have:

<DatabaseGenerated(DatabaseGeneratedOption.Computed)>
Public Property CreatedDate As DateTime

Will this work, or will I need to use a nullable even though the actual column should be not null, so EF doesn't send a value when it hasn't been set:

<DatabaseGenerated(DatabaseGeneratedOption.Computed)>
Public Property CreatedDate As DateTime?

Or is there a better solution out there?

I don't want EF to handle my defaults - I know this is available to me but not possible in my current situation.

1
15
11/20/2014 11:31:42 AM

Accepted Answer

Currently in EF6 there is not an attribute to define database functions used for a certain property default value. You can vote on Codeplex to get it implemented:

https://entityframework.codeplex.com/workitem/44

The accepted way to implement something like that is to use Computed properties with Migrations where you specify the default database function.

Your class could look like this in C#:

public class MyEntity
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime Created { get; set; }
}

The computed property doesn't have to be nullable.

Then you have to run a migration and modify it by hand to include the default SQL function. A migration could look like:

public partial class Initial : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.MyEntities",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                    Created = c.DateTime(nullable: false, defaultValueSql: "GetDate()"),
                })
            .PrimaryKey(t => t.Id);

    }

    public override void Down()
    {
        DropTable("dbo.MyEntities");
    }
}

You will notice the defaultValueSql function. That is the key to get the computation working

21
11/20/2014 5:02:49 PM

Popular Answer

Accepted answer is correct for EF6, I'm only adding EF Core solution; (also my solution focuses on changing the default-value, rather than creating it properly the first time)

There is still no Data-Attribute in EF Core.

And you must still use the Fluent API; it does have a HasDefaultValue

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Rating)
        .HasDefaultValue(3);
}

Note, there is also HasDefaultValueSql for NULL case:

        .HasDefaultValueSql("NULL");

And you can also use the Migrations Up and Down methods, you can alter the defaultValue or defaultValueSql but you may need to drop Indexes first. Here's an example:

public partial class RemovingDefaultToZeroPlantIdManualChange : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropIndex(
            name: "IX_TABLE_NAME_COLUMN_NAME",
            table: "TABLE_NAME"
        );

        migrationBuilder.AlterColumn<int>(
            name: "COLUMN_NAME",
            table: "TABLE_NAME",
            nullable: true,
            //note here, in the Up method, I'm specifying a new defaultValue:
            defaultValueSql: "NULL",
            oldClrType: typeof(int));

        migrationBuilder.CreateIndex(
            name: "IX_TABLE_NAME_COLUMN_NAME",
            table: "TABLE_NAME",
            column: "COLUMN_NAME"
        );
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropIndex(
            name: "IX_TABLE_NAME_COLUMN_NAME",
            table: "TABLE_NAME"
        );

        migrationBuilder.AlterColumn<int>(
            name: "COLUMN_NAME",
            table: "TABLE_NAME",
            nullable: true,
            //note here, in the Down method, I'll restore to the old defaultValue:
            defaultValueSql: "0",
            oldClrType: typeof(int));

        migrationBuilder.CreateIndex(
            name: "IX_TABLE_NAME_COLUMN_NAME",
            table: "TABLE_NAME",
            column: "COLUMN_NAME"
        );


    }
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow