46

在 Entity Framework Code First 方法中,如何为 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 ?
    }
}
4

7 回答 7

24

随着 Entity Framework 4.3 的发布,您可以通过迁移来做到这一点。

EF 4.3 代码优先迁移演练

因此,使用您的示例将类似于:

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
    }
}
于 2012-02-24T14:58:58.520 回答
15

您可以通过类的构造函数设置默认值。这是我当前项目中的一个类,使用 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; }
}
}
于 2011-06-01T12:58:14.597 回答
7

我知道这个话题已经持续了一段时间,我也遇到了同样的问题。到目前为止,我还没有找到一种解决方案,可以将整个东西放在一个地方,这样代码仍然可读。

在创建用户时,我希望通过对象本身设置一些字段private setters,例如 GUID 和创建日期,而不是“污染”构造函数。

我的用户类:

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 };
}));
于 2012-05-30T20:20:02.520 回答
4

不幸的是你不能。http://social.msdn.microsoft.com/Forums/en/adonetefx/thread/a091ccd6-0ba8-4d4f-8f5e-aafabeb258e4

于 2010-06-29T07:03:52.307 回答
3

如果您希望 SQL Server 以实现此目的的方式提供默认日期,重要的部分是 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
    }
}
于 2014-05-22T21:09:37.977 回答
3

我不确定什么版本的 EF 可用,但从版本 5 开始,你肯定可以处理这个问题。只需在 SQL 中的列上设置 GetDate() 的默认值,在 TSQL 或设计器中,然后设置您的 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 属性设为可为空。

于 2013-04-02T23:06:40.873 回答
0

除了使用DB MIGRATIONS并启用迁移之外别无他法,您必须像这样设置您的属性

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

之后,创建数据库后,您必须按照以下步骤启用迁移。转到程序管理器控制台并逐个执行以下命令

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