我正在尝试在模型中配置一个字段,该字段将通过插入和更新进行修改。
尝试了多种方法,但仍然可以找到满足我的要求的正确配置。
示例:
public class Author
{
public DateTime UpdatedAt { get; set; }
}
我有字段 UpdatedAt ,它要在 SQL 服务器端通过插入/更新行来计算..
到目前为止我已经尝试过以下
public class Author
{
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime UpdatedAt { get; set; }
}
public class Author
{
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
modelbuilder.Entity<Author>().Property(a =>a.UpdatedAt).HasDefaultValueSql("GetUtcDate()").ValueGeneratedOnAddOrUpdate();
modelbuilder.Entity<Author>().Property(a => a.UpdatedAt).ValueGeneratedOnAddOrUpdate();
5.尝试了Fluent API 2,但没有满足要求。每当有插入或更新时,它都会更新该列的所有行。
modelbuilder.Entity<Author>().Property(a => a.UpdatedAt).HasComputedColumnSql("GetUtcDate()");
我不是 EF 专家,但根据 documentation,更新时生成的日期时间值需要通过触发器创建(这与我对 SQL Server 的了解一致)。
在 SQL Server 中,执行此操作的方法是编写一个用于插入和更新的触发器,该触发器将更新指定的列。
但是请注意,文档中提供的触发器示例存在缺陷,因为它假设仅进行单行更新。在 SQL Server 中,触发器是根据语句而不是行触发的,因此当您更新多行(或 EF 中的实例)时,触发器将被触发一次。
所以正确的写法是这样的
CREATE TRIGGER [dbo].[Author_UPDATE] ON [dbo].[Author]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;
UPDATE A
SET LastUpdated = GETDATE()
FROM Author As A
INNER JOIN Inserted As I
ON A.Id = I.Id;
END