Значение по умолчанию для столбца SQL с Entity Framework

Я пытаюсь использовать Code-First EF6 со значениями по умолчанию SQL.

Например, у меня есть "CreatedDate" column/property, но не null, с по умолчанию в SQL "getdate()"

Как мне представить это в моей модели кода? В настоящее время у меня есть:

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

Будет ли это работать, или мне нужно использовать значение NULL, даже если фактический столбец должен быть не нулевым, поэтому EF не отправляет значение, если оно не было установлено:

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

Или там есть лучшее решение?

Я не хочу, чтобы EF обрабатывал мои значения по умолчанию - я знаю, что это доступно мне, но не возможно в моей текущей ситуации.

Ответ 1

В настоящее время в EF6 нет атрибута для определения функций базы данных, используемых для определенного значения по умолчанию для свойства. Вы можете проголосовать за Codeplex, чтобы реализовать его:

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

Принятый способ реализовать что-то подобное - использовать свойства Computed с Migrations, где вы указываете функцию базы данных по умолчанию.

Ваш класс может выглядеть так на С#:

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

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

Вычисленное свойство не должно быть нулевым.

Затем вам нужно выполнить миграцию и вручную изменить ее, чтобы включить функцию SQL по умолчанию. Миграция может выглядеть так:

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

Вы заметите функцию defaultValueSql. Это ключ, чтобы заставить вычисление работать

Ответ 2

Принятый ответ верен для EF6, я только добавляю решение EF Core; (также мое решение фокусируется на изменении значения по умолчанию, а не на его правильном создании в первый раз)

В EF Core до сих пор нет атрибута данных.

И вы все равно должны использовать Fluent API; у него есть HasDefaultValue

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

Обратите внимание, что также есть HasDefaultValueSql для случая NULL:

        .HasDefaultValueSql("NULL");

И вы также можете использовать методы Migrations Up и Down, вы можете изменить defaultValue или defaultValueSql но вам может понадобиться сначала удалить Indexes. Вот пример:

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


    }
}

Ответ 3

попробуй с этим. Этот код вставляет по умолчанию текущую дату

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