SQL Server 2005 数据库表有一个列“createdon”,其默认值设置为 getdate()。我正在尝试使用实体框架添加记录。“createdon”列未更新。
我是否错过了实体框架中的任何属性,请提出建议。
SQL Server 2005 数据库表有一个列“createdon”,其默认值设置为 getdate()。我正在尝试使用实体框架添加记录。“createdon”列未更新。
我是否错过了实体框架中的任何属性,请提出建议。
这是实体框架存在问题的少数问题之一。假设您有一个如下所示的类:
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; }
}
现在,您要插入一个新元素:
using(var context = new YourContext())
{
context.MyEntities.Add(new MyEntity())
}
由于 EDMX 中的定义,Entity Framework 知道如何处理自增主键。它不会尝试为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())
}
编辑:为了扩展这一点,这是一个无法解决的问题的原因是因为字段背后的含义autoincrement
和具有default
值约束的字段。根据定义,自动增量字段应始终由服务器处理,使用种子和所有爵士乐。除非您使用了SET IDENTITY INSERT ON
. 然而,默认值只是提示“如果我没有指定任何值,请使用它”。因为 .NET 中的值类型不能为空,所以总会有一个值,而 Entity Framework 无法推断该字段的默认值,当时,意味着您希望它在 SQL 服务器上默认。
除了使用设计器和已经显示的一些更漂亮的东西之外,您还可以通过简单地设置DatabaseGenerated
字段上的属性来将列标记为正在计算:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedOn { get; set; }
我通过告诉 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);
....