2014-11-20 20 views
7

Sto tentando di utilizzare l'EF6 code-First con valori SQL predefiniti.Valore predefinito colonna SQL con Entity Framework

Per esempio, ho una colonna "CreatedDate"/proprietà non nullo con un valore predefinito in SQL di "GETDATE()"

Come faccio a rappresentare questo nel mio codice di modello? Attualmente ho:

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

questo lavoro, o avrò bisogno di usare un annullabile anche se la colonna reale dovrebbe essere non nullo, in modo da EF non invia un valore quando non è stata impostata:

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

Oppure c'è una soluzione migliore là fuori?

Non voglio che EF gestisca le mie impostazioni predefinite - so che questo è disponibile ma non è possibile nella mia situazione attuale.

risposta

12

Attualmente in EF6 non esiste un attributo per definire le funzioni del database utilizzate per un determinato valore predefinito della proprietà. Puoi votare su CodePlex per farlo implementato:

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

Il modo accettato di implementare qualcosa di simile è quello di utilizzare le proprietà Computed con Migrations in cui si specifica la funzione di database predefinito.

La classe potrebbe apparire come questo in C#:

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

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

La proprietà calcolata non deve essere annullabile.

Quindi è necessario eseguire una migrazione e modificarla manualmente per includere la funzione SQL predefinita. Potrebbe essere una migrazione:

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

Si noterà la funzione defaultValueSql. Questa è la chiave per far funzionare il calcolo

+0

Grande, grazie, per ora ci vado con questo. – Carl

+0

Prego;) –

2

La risposta accettata è corretta, basta aggiornare con la soluzione EF Core; (anche la mia soluzione si concentra sulla modifica del valore predefinito, anziché crearla correttamente la prima volta)

Non esiste ancora un attributo di dati.

E si deve ancora utilizzare l'API Fluent; esso ha un HasDefaultValue

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

Nota, c'è anche HasDefaultValueSql per caso NULL:

 .HasDefaultValueSql("NULL"); 

E si può anche utilizzare le Migrazioni Up e Down metodi, è possibile modificare la defaultValue o defaultValueSql ma si potrebbe essere necessario eliminare prima gli indici. Ecco un esempio:

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


    } 
} 
Problemi correlati