通过 Entity Framework 模式创建时,SQL 服务器 table 中未设置默认值

Default values doesn't set in SQL Server table when creating by Entity Framework mode

我有很多包含默认值的 table,例如 CreatedDateTime (getutcdate())。但是现在,存储的是值 0001-01-01 00:00:00.0000000。

--> 这是无效的,我必须为每个数据库模型更新 (edmx) 手动为每个 table 执行此操作。如何自动将所有 StoreGeneratedPattern 更新为 Computed?或者为什么它不自动计算?

--> ado.net 生成所有属性,我无法再次生成 CreatedDateTime.

有自动解决方案吗?

我正在使用 Entity Framework 和 ado.net。

Person person = new Person()
{
    Id = id,
    Name = name,
};
AddToPerson(person);
SaveChanges();

我想用上面的。我不想使用以下内容并再次分配 CreatedDeteTime,因为它是在 MSSQL 中分配的,默认值为 getutcdate()。

Person person = new Person()
{
    Id = id,
    Name = name,
    CreatedDeteTime = DateTime.UtcNow;
};
AddToPerson(person);
SaveChanges();

如果您有SQL INSERT 声明 省略了 有问题的列。

所以如果你插入

 INSERT INTO dbo.Person(Id, Name) VALUES (42, "John Doe")

--> 那么你的 CreatedDateTime 自动设置为 GETUTCDATE() 值。

不幸的是,如果您在 EF 模型 class 中映射了此列,那么这不是会发生什么。如果您在 C# 代码中创建 Person 的实例,并且 CreatedDateTime 列实际上是模型 class 的一部分,那么 EF 将使用类似这样的东西来插入新人:

 INSERT INTO dbo.Person(Id, Name, CreatedDateTime) VALUES (42, "John Doe", NULL)

并且从现在 NULL 实际上提供给 CreatedDateTime 列,这就是将要存储的值 - 或者它可能是一个空字符串- 无论如何,在 INSERT 语句中指定了 ,因此未应用配置的默认约束 .

因此,如果您想让 SQL 服务器使用默认设置,您需要确保 而不是 INSERT 声明。您可以通过以下方式做到这一点:

  1. 有一个单独的模型 class 仅用于插入, 包括那些有问题的列 - 例如有一个 NewPerson 实体,它也映射到 Person table,但仅由 NameID 组成。由于这些属性不存在,因此 EF 不能也不会使用它们生成 INSERT 语句 - 因此 SQL 服务器默认约束将启动

  2. INSERT 方法映射到 SQL 服务器存储过程并通过显式 not 指定来处理该过程中的插入您希望采用默认值的那些列

可能我错了,但我有一个问题。 如果您需要在您的数据库 Table 中保存默认日期,为什么要尝试从程序级别保存另一个日期?我的意思是,创建程序并在程序级别保存日期很容易。类似于 (select getdate()...)。

我找到了两个解决方案:

1- 此解决方案解决了具有相同 属性 的所有实体,例如 CreatedDateTime

public partial class MyEntities : ObjectContext
    {
        public override int SaveChanges(SaveOptions options)
        {
            this.DetectChanges();

            foreach (var insert in this.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added))
            {
                if (insert.Entity.GetType().GetProperty("CreatedDateTime") != null && insert.Entity.GetType().GetProperty("CreatedDateTime").GetType().Name == "DateTime" && (DateTime)(insert.Entity.GetType().GetProperty("CreatedDateTime").GetValue(insert.Entity)) == DateTime.Parse("0001-01-01 00:00:00.0000000"))
                    insert.Entity.GetType().GetProperty("CreatedDateTime").SetValue(insert.Entity, DateTime.UtcNow, null);                
            }
            return base.SaveChanges(options);
        }
    }

参考:

2-

public partial class Person
        {
            public Person()
            {
                this.CreatedDateTime = DateTime.UtcNow;
            }
        }

参考:DB default value ignored when creating Entity Framework model