2014-11-20 15 views
7

Ich versuche, Code-First EF6 mit SQL-Standardwerten zu verwenden.SQL-Spalte Standardwert mit Entity Framework

Zum Beispiel, ich habe eine "CreatedDate" Spalte/Eigenschaft nicht null mit einem Standard in SQL von "getdate()"

Wie gebe ich das in meinem Code Modell? Zur Zeit habe ich:

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

wird diese Arbeit, oder brauche ich eine NULL festlegbare zu verwenden, auch wenn die tatsächliche Spalte nicht null sein sollte, so ist EF keinen Wert senden, wenn es nicht gesetzt ist:

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

Oder gibt es eine bessere Lösung da draußen?

Ich möchte nicht EF mit meinen Standardeinstellungen umgehen - ich weiß, dass dies für mich verfügbar ist, aber nicht in meiner derzeitigen Situation möglich.

Antwort

12

Derzeit gibt es in EF6 kein Attribut zum Definieren von Datenbankfunktionen, die für einen bestimmten Eigenschaftsstandardwert verwendet werden. Sie können auf Codeplex abstimmen, um es umgesetzt:

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

die akzeptierte Möglichkeit, etwas zu implementieren wie die Computed Eigenschaften mit Migrations zu verwenden ist, wo Sie die Standard-Datenbankfunktion angeben.

Ihre Klasse könnte wie folgt in C# aussehen:

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

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

Die berechnete Eigenschaft keine Nullwerte enthalten sein muss.

Dann müssen Sie eine Migration ausführen und manuell ändern, um die Standard-SQL-Funktion einzuschließen. Eine Migration könnte wie folgt aussehen:

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

Sie werden die defaultValueSql-Funktion bemerken. Das ist der Schlüssel, um die Berechnung zum Laufen zu bringen

+0

Großartig, danke, ich werde mit diesem für jetzt gehen. – Carl

+0

Gern geschehen;) –

2

Akzeptierte Antwort ist korrekt, nur Aktualisierung mit EF Core Lösung; (Auch meine Lösung konzentriert sich darauf, den Standardwert zu ändern, anstatt ihn beim ersten Mal richtig zu erstellen)

Es gibt immer noch kein Datenattribut.

Und Sie müssen immer noch die Fluent-API verwenden; es macht einen Hinweis HasDefaultValue

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

haben, gibt es auch HasDefaultValueSql für NULL Fall:

 .HasDefaultValueSql("NULL"); 

Und Sie können auch die Migrationen Up und Down Methoden verwenden, können Sie die defaultValue oder defaultValueSql ändern, aber Sie Möglicherweise müssen Sie zuerst die Indizes löschen. Hier ist ein Beispiel:

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


    } 
}