.net 如何在 EF CF 中为 POCO 设置默认值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3137738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 14:27:28  来源:igfitidea点击:

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

.netentity-frameworkef-code-firstentity-framework-4

提问by Andy

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

在实体框架代码优先方法中,如何为 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 ?
    }
}

回答by Chris Pacey

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

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

EF 4.3 Code First Migrations Walkthrough

EF 4.3 Code First 迁移演练

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

回答by Gavin Coates

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:

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

回答by 321X

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.

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

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 = "[email protected]";
    c.Salt = salt;
    c.Password = "mypass";
    c.Roles = new List<Role> { adminRole, userRole };
}));

回答by S Walsh

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:

我不确定这可用的 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);
    }
}

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

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

回答by user3591722

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)

在您希望 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
    }
}

回答by coder89

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

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

[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 AlterMyTableHere AlterMyTablecan 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-DatabaseAnd now if you see the Persontable in your database and then navigate to the CreatedOncolumn 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 CreatedOnfor you.
  • 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为您更新该列。