实体框架 - 在sql server表中未设置默认值

Chr*_*web 6 c# sql-server-2005 entity-framework-4

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

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

Sim*_*ger 12

这是Entity Framework存在问题的少数几个问题之一.假设您有一个类似于以下的类:

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

using(var context = new YourContext()) 
{
    context.MyEntities.Add(new MyEntity())
}
Run Code Online (Sandbox Code Playgroud)

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

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

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())
}   
Run Code Online (Sandbox Code Playgroud)

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


Pat*_*man 10

在使用设计器和已经显示的一些更漂亮的东西旁边,您还可以通过简单地DatabaseGenerated在字段上设置属性来标记列的计算:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedOn { get; set; }
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案,因为您可以轻松地将其放在局部类中。即使您重新生成模型,它也将继续起作用。 (2认同)

Ton*_* L. 8

您可以设置StoreGeneratedPatternComputed(如马尔科姆建议)在实体数据模型的GUI为好.

  1. 在Visual Studio中打开.edmx文件
  2. 打开字段的属性(单击字段 - >点击F4或右键单击 - >属性)
  3. 设置StoreGeneratedPatternComputed在属性窗口如下图所示:

在此输入图像描述


Mal*_*ine 6

我已经解决了这个问题,告诉EF该列是"计算的",因此应该单独插入.

如果查看生成的实体的配置

       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);
                    ....
Run Code Online (Sandbox Code Playgroud)