Sto cercando di usare l'EF6 Code-First con valori SQL predefiniti.
Ad esempio, ho una colonna / proprietà "CreatedDate" non null con un valore predefinito in SQL di "getdate ()"
Come posso rappresentarlo nel mio modello di codice? Attualmente ho:
<DatabaseGenerated(DatabaseGeneratedOption.Computed)>
Public Property CreatedDate As DateTime
Funzionerà, o dovrò usare un nullable anche se la colonna effettiva non dovrebbe essere nulla, quindi EF non invia un valore quando non è stato impostato:
<DatabaseGenerated(DatabaseGeneratedOption.Computed)>
Public Property CreatedDate As DateTime?
O 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.
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 implementarlo:
https://entityframework.codeplex.com/workitem/44
Il modo accettato per implementare qualcosa del genere è utilizzare le proprietà Computed
con le Migrations
dove si specifica la funzione di database predefinita.
La tua classe potrebbe avere questo aspetto 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. Una migrazione potrebbe essere simile a:
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");
}
}
Noterai la funzione defaultValueSql. Questa è la chiave per far funzionare il calcolo
La risposta accettata è corretta per EF6, sto solo aggiungendo la soluzione EF Core ; (anche la mia soluzione si concentra sulla modifica del valore predefinito, piuttosto che crearlo correttamente la prima volta )
Non esiste ancora un attributo dati in EF Core
.
E devi ancora usare l'API Fluent; ha un valore HasDefaultValue
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Rating)
.HasDefaultValue(3);
}
Nota, esiste anche HasDefaultValueSql
per il caso NULL:
.HasDefaultValueSql("NULL");
Inoltre, è possibile utilizzare i metodi Migrazione Up
e Down
, è possibile modificare il valore defaultValue
o defaultValueSql
ma potrebbe essere necessario prima eliminare 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"
);
}
}