Wie legen Sie in Entity Framework Code First einen Standardwert für eine Eigenschaft in der EntityConfiguration-Klasse des POCO fest?
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedOn { get; set; }
}
public class PersonConfiguration : EntityConfiguration<Person>
{
public PersonConfiguration()
{
Property(p => p.Id).IsIdentity();
Property(p => p.Name).HasMaxLength(100);
//set default value for CreatedOn ?
}
}
Mit dem Release von Entity Framework 4.3 können Sie dies über Migrationen durchführen.
EF 4.3 - Erste Schritte für die erste Migration
An Ihrem Beispiel würde es also so aussehen:
public partial class AddPersonClass : DbMigration
{
public override void Up()
{
CreateTable(
"People",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(maxLength: 100),
CreatedOn = c.DateTime(nullable: false, defaultValue: DateTime.UtcNow)
})
.PrimaryKey(t => t.Id);
}
public overide void Down()
{
// Commands for when Migration is brought down
}
}
Sie können die Standardwerte über den Konstruktor für die Klasse festlegen. Hier ist eine Klasse, die ich in meinem aktuellen Projekt mit MVC3 und Entity Framework 4.1 habe:
namespace MyProj.Models
{
using System;
using System.Collections.Generic;
public partial class Task
{
public Task()
{
this.HoursEstimated = 0;
this.HoursUsed = 0;
this.Status = "To Start";
}
public int ID { get; set; }
public string Description { get; set; }
public int AssignedUserID { get; set; }
public int JobID { get; set; }
public Nullable<decimal> HoursEstimated { get; set; }
public Nullable<decimal> HoursUsed { get; set; }
public Nullable<System.DateTime> DateStart { get; set; }
public Nullable<System.DateTime> DateDue { get; set; }
public string Status { get; set; }
public virtual Job Job { get; set; }
public virtual User AssignedUser { get; set; }
}
}
Ich weiß, dass dieses Thema für eine Weile anhält, und ich bin zu einem ähnlichen Thema gekommen. Bisher konnte ich keine Lösung für mich finden, die das Ganze an einem Ort zusammenhält, sodass der Code immer noch lesbar ist.
Bei der Erstellung eines Benutzers möchte ich, dass einige Felder vom Objekt selbst über private setters
festgelegt werden, z. a GUID und Erstellungsdatum und den Konstruktor nicht "verschmutzen".
Meine Benutzerklasse:
public class User
{
public static User Create(Action<User> init)
{
var user = new User();
user.Guid = Guid.NewGuid();
user.Since = DateTime.Now;
init(user);
return user;
}
public int UserID { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual ICollection<Widget> Widgets { get; set; }
[StringLength(50), Required]
public string Name { get; set; }
[EmailAddress, Required]
public string Email { get; set; }
[StringLength(255), Required]
public string Password { get; set; }
[StringLength(16), Required]
public string Salt { get; set; }
public DateTime Since { get; private set; }
public Guid Guid { get; private set; }
}
Aufrufcode:
context.Users.Add(User.Create(c=>
{
c.Name = "Name";
c.Email = "[email protected]";
c.Salt = salt;
c.Password = "mypass";
c.Roles = new List<Role> { adminRole, userRole };
}));
Leider kannst du nicht. http://social.msdn.Microsoft.com/Forums/de/adonetefx/thread/a091ccd6-0ba8-4d4f-8f5e-aafabeb258e4
Ich bin nicht sicher, ab welcher Version von EF diese Version verfügbar ist, aber ab Version 5 können Sie sicher damit umgehen. Setzen Sie einfach einen Standardwert von GetDate () für die Spalte in SQL, entweder in TSQL oder im Designer, und richten Sie Ihre EF-Klassen wie folgt ein:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedOn { get; set; }
}
public class PersonConfiguration : EntityConfiguration<Person>
{
public PersonConfiguration()
{
Property(p => p.Id).IsIdentity();
Property(p => p.Name).HasMaxLength(100);
this.Property(p => p.CreatedOn ).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed);
}
}
Beachten Sie, dass Sie die Datenbankspalte oder die POCO-Eigenschaft nicht auf Null setzen müssen.
Wenn Sie möchten, dass SQL Server ein Standarddatum bereitstellt, so wie Sie dies erreichen möchten, ist defaultValueSql: "GETDATE ()" der Standardwert des SQL-Servers und nicht nur den Zeitpunkt, zu dem das Skript ausgeführt wurde (dh DateTime.UtcNow)
public partial class AddPersonClass : DbMigration
{
public override void Up()
{
CreateTable(
"People",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(maxLength: 100),
CreatedOn = c.DateTime(nullable: false, defaultValueSql: "GETDATE()")
})
.PrimaryKey(t => t.Id);
}
public overide void Down()
{
// Commands for when Migration is brought down
}
}
Es gibt keine andere Möglichkeit, als DB MIGRATIONS zu verwenden, und um die Migrationen zu aktivieren, müssen Sie Ihre Eigenschaft so einstellen
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedOn { get; set; }
Danach müssen Sie nach dem Erstellen der Datenbank die folgenden Schritte ausführen, um die Migrationen zu aktivieren. Gehen Sie zur Programm-Manager-Konsole und führen Sie die folgenden Befehle einzeln aus
PM> Enable-Migrations
PM> Add-Migration AlterMyTable
Hier AlterMyTable kann ein beliebiger Name sein Dadurch wird eine Datei unter dem neu hinzugefügten Migrationsordner in Ihrer Lösung erstellt. currentTimestamp_AlterMyTable.cs
- Kopieren Sie nun Folgendes in die Up-Methode von currentTimestamp_AlterMyTable.cs AlterColumn("Person", "CreatedOn", n => n.DateTime(nullable: false, defaultValueSql: "SYSUTCDATETIME()"));
Führen Sie anschließend den letzten Befehl in der Programm-Manager-Konsole ausPM> Update-Database
Wenn Sie nun die Person
-Tabelle in Ihrer Datenbank sehen und dann zur CreatedOn
-Spalte navigieren, sollte sie den Standardwert als SYSUTCDATETIME()
haben. Wenn Sie nun versuchen, Daten in diese Tabelle einzufügen, aktualisiert Ihre Datenbank diese Spalte automatisch CreatedOn
für Sie.