如何在EF CF中设置POCO的默认值?

在Entity Framework 4 Code Only(CTP3)中,如何为POCO的EntityConfiguration类中的属性设置默认值?

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 ? } } 

随着Entity Framework 4.3的发布,您可以通过迁移来完成这个任务。

EF 4.3 Code First迁移演练

所以使用你的例子,它会是这样的:

 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 } } 

您可以通过类的构造函数设置默认值。 这是我在当前项目中使用MVC3和Entity Framework 4.1的一个类:

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

我知道这个话题正在进行一段时间,我走进了一个同样的问题。 到目前为止,我找不到解决scheme,把整个事情放在一起,所以代码仍然可读。

在创build用户时,我想通过private setters设置对象本身的某些字段,例如GUID和Creation Date,而不是“污染”构造函数。

我的用户类:

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

调用代码:

 context.Users.Add(User.Create(c=> { c.Name = "Name"; c.Email = "some@one.com"; c.Salt = salt; c.Password = "mypass"; c.Roles = new List<Role> { adminRole, userRole }; })); 

我不确定EF的版本是否可用,但是从版本5开始,您肯定可以处理这个问题。 只需在TSQL或devise器中的SQL列中设置GetDate()的默认值,然后按如下方式设置EF类:

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

请注意,您不需要使数据库列可以为空或POCO属性。

在希望SQL Server提供缺省date的情况下,重要的部分是defaultValueSql:“GETDATE()”,它将设置sql server默认值,而不仅仅是计算脚本运行的时间(即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 } } 

除了使用数据库迁移以外 ,没有别的办法,并且启用迁移,您必须像这样设置属性

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

在此之后,一旦您的数据库被创build,您必须按照以下步骤启用迁移。 转到程序pipe理器控制台并执行以下命令逐个命令

  • PM> Enable-Migrations
  • PM> Add-Migration AlterMyTable这里AlterMyTable可以是任何名字。 这将在您的解决scheme中的新添加的Migrations文件夹下创build一个文件currentTimestamp_AlterMyTable.cs – 将以下内容复制到currentTimestamp_AlterMyTable.cs的Up方法
  • AlterColumn("Person", "CreatedOn", n => n.DateTime(nullable: false, defaultValueSql: "SYSUTCDATETIME()")); 然后在程序pipe理器控制台中执行最后一个命令
  • PM> Update-Database现在,如果您在数据库中看到Person表,然后导航到CreatedOn列,它应该具有SYSUTCDATETIME()的默认值即现在如果您尝试向该表中插入一些数据,数据库将自动为您更新此栏CreatedOn