开发者

How to set default value for POCO's in EF CF?

In Entity Framework Code First approach, how do you set a default value for a property in the POCO's EntityConfiguration class?

public class Person
{
    public 开发者_StackOverflow社区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 ?
    }
}


With the release of Entity Framework 4.3 you can do this through Migrations.

EF 4.3 Code First Migrations Walkthrough

So using your example it would be something like:

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


You can set the default values via the constructor for the class. Here is a class I have in my current project, using MVC3 and 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; }
}
}


I know this topic is going on for a while and I walked into some kind of the same issue. So far I couldn't find a solution for me that keeps the whole thing together at one place so the code is still readable.

At creation of an user I want to have some fields set by the object itself via private setters, e.g. a GUID and Creation Date and not 'polluting' the constructor.

My User class:

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

Calling code:

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


Unfortunately you can't. http://social.msdn.microsoft.com/Forums/en/adonetefx/thread/a091ccd6-0ba8-4d4f-8f5e-aafabeb258e4


I'm not sure as of what version of EF this becomes available, but as of version 5 for sure you can handle this. Just set a default value of GetDate() on the column in SQL, either in TSQL or the designer, then setup your EF classes as follows:

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

Note that you don't need to make the database column nullable, or the POCO property.


In the case where you want SQL Server to provide a default date the way you would accomplish this is, the important part is defaultValueSql: "GETDATE()" which will set the sql server default, not just evaluate to the time the script was run (i.e. 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
    }
}


There is no other way but to use DB MIGRATIONS and to enable the migrations you must set your property like this

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

And after that once your database is created you must follow the following steps to enable the migrations. Go to Program Manager console and Execute the following commands one by ones command

  • PM> Enable-Migrations
  • PM> Add-Migration AlterMyTable Here AlterMyTable can be any name. this will create a file under newly added Migrations folder in your solution currentTimestamp_AlterMyTable.cs -Now copy the following to the Up method of currentTimestamp_AlterMyTable.cs
  • AlterColumn("Person", "CreatedOn", n => n.DateTime(nullable: false, defaultValueSql: "SYSUTCDATETIME()")); And after that execute the last command in your Program Manager Console
  • PM> Update-Database And now if you see the Person table in your database and then navigate to the CreatedOn column it should be having the Default value as SYSUTCDATETIME() i.e. now if you try to insert some data to this table your database will automatically update this column CreatedOn for you.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜