关于C#:Entity Framework-在SQL Server表中未设置默认值

Entity Framework - default values doesn't set in sql server table

SQL Server 2005数据库表具有一列" createdon",其默认值设置为getdate()。 我正在尝试使用实体框架添加记录。 'createdon'列未更新。

我是否错过了Entity框架中的任何属性,请提出建议。


这是实体框架存在问题的少数问题之一。假设您有一个看起来像这样的课程:

1
2
3
4
5
6
7
8
public class MyEntity
{
    // Id is a PK on the table with Auto-Increment
    public int Id { get; set; }

    // CreatedOn is a datetime, with a default value
    public DateTime CreatedOn { get; set; }
}

现在,您要插入一个新元素:

1
2
3
4
using(var context = new YourContext())
{
    context.MyEntities.Add(new MyEntity())
}

由于EDMX中的定义,实体框架知道如何处理自动增量主键。它不会尝试为Id属性插入值。但是,就实体框架而言,CreatedOn具有一个值:默认值DateTime。因为Entity Framework无法说"好,它有一个值,但我应该忽略它",所以它将主动插入具有CreatedOn属性值的记录,从而绕过表上列定义的默认值。

没有简单的方法可以做到这一点。插入该项时,可以将CreatedOn属性设置为DateTime.Now。或者,您可以创建一个接口和一个扩展方法对:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface ICreatedOn
{
    public DateTime CreatedOn { get; set; }
}

public partial class MyEntity : ICreatedOn
{

}

public static TEntity AsNew<TEntity>(this TEntity entity) where TEntity : ICreatedOn
{
    if(entity != null)
        entity.CreatedOn = DateTime.Now;

    return entity;
}

using(var context = new YourContext())
{
    context.MyEntities.Add(new MyEntity().AsNew())
}

编辑:在这一点上进行扩展,之所以无法解决这个问题,是因为autoincrement字段和具有default值约束的字段的含义。根据定义,自动递增字段应始终由服务器使用种子和所有爵士乐来处理。除非您已使用SET IDENTITY INSERT ON,否则无法为插入上的自动增量字段指定值。但是,默认值只是一个提示,提示"如果我未指定任何值,请使用此值"。由于.NET中的值类型不能为null,因此始终会有一个值,并且Entity Framework无法推断当时该字段的默认值意味着您希望在SQL Server上将其默认为默认值。


除了使用设计器和已经显示的更多漂亮功能之外,您还可以通过简单地在字段上设置DatabaseGenerated属性,将列标记为正在计算:

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


您也可以在实体数据模型的GUI中将StoreGeneratedPattern设置为Computed(如Malcolm建议)。

  • 在Visual Studio中打开您的.edmx文件
  • 打开字段的属性(单击字段->点击
    F4或右键单击->属性)
  • 在属性窗口中将StoreGeneratedPattern设置为Computed
    如下所示:
  • enter image description here


    通过告诉EF该列是"计算的",因此可以解决此问题,因此应单独留给插入。

    如果您在生成的实体的配置中查找

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
           namespace Data.Context
            {
                // Table
                internal partial class MyTableConfiguration : EntityTypeConfiguration<MyTable>
                {
                    public MyTableConfiguration(string schema ="dbo")
                    {    
                        ToTable(schema +".MyTable");
                        HasKey(x => x.Id);

                        Property(x => x.ColumnName).HasColumnName("ColumnName").IsOptional().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
                        ....