我有一个表
UserSession
,其中CreatedTime
列的datetime
不为空类型。在该表中,我对此列创建了一个约束,如下所示:
CONSTRAINT [CK__UserSession__CreatedTi__690797E6] CHECK ([CreatedTime] <= GETUTCDATE())
当我尝试像这样将新实体保存到数据库时
var newSession = new UserSession
{
// ...
CreatedTime = DateTime.UtcNow
};
_dbContext.UserSessions.Add(newSession);
await _dbContext.SaveChangesAsync();
它会抛出有关保存进度失败的异常,如下所示
Microsoft.EntityFrameworkCore.DbUpdateException:保存实体更改时发生错误。有关详细信息,请参阅内部异常。
Microsoft.Data.SqlClient.SqlException:INSERT 语句与 CHECK 约束“CK__UserSession__CreatedTi__33D4B598”冲突。冲突发生在数据库“testdb”、表“dbo.UserSession”、列“CreatedTime”中。
看起来保存的实体违反了约束。
那么我该如何解决这样的实体的保存数据问题呢?
填充值的应用程序服务器/客户端与执行约束检查的数据库之间的
DateTime
同步将会出现问题。
对于诸如创建的日期时间值之类的事情,我建议让数据库在创建行时处理填充这些值。在列上设置默认值作为使用
GETUTCDATE()
的约束的一部分,然后将实体标记为计算列:
[DateTimeKind(DateTimeKind.Utc), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedTime { get; protected set; }
现在您不需要显式设置该值,该属性在任何情况下都不允许您使用设置器。当插入一行时,它将填充当前的 UTC 时间戳。