使用 Fluent API 计算更新和插入时归档

问题描述 投票:0回答:1

我正在尝试在模型中配置一个字段,该字段将通过插入和更新进行修改。

尝试了多种方法,但仍然可以找到满足我的要求的正确配置。

示例:

public class Author
{
   
    public DateTime UpdatedAt { get; set; } 
}

   

我有字段 UpdatedAt ,它要在 SQL 服务器端通过插入/更新行来计算..

到目前为止我已经尝试过以下

  1. 尝试过这样的数据标注,但不满足要求。
public class Author
{
   [DatabaseGenerated(DatabaseGeneratedOption.Computed)]

    public DateTime UpdatedAt { get; set; } 
}
  1. 尝试过像这样的数据注释和设置默认值,但不满足要求。
public class Author
{
   [DatabaseGenerated(DatabaseGeneratedOption.Computed)]

        public DateTime UpdatedAt { get; set; }  = DateTime.UtcNow;
}
  1. 尝试了 Fluent API 1 但不满足要求,是在插入时设置值但在更新时不修改它。

modelbuilder.Entity<Author>().Property(a =>a.UpdatedAt).HasDefaultValueSql("GetUtcDate()").ValueGeneratedOnAddOrUpdate();

  1. 尝试过Fluent API 2,但不满足要求。既没有设置值,也没有修改它。

modelbuilder.Entity<Author>().Property(a => a.UpdatedAt).ValueGeneratedOnAddOrUpdate(); 
5.尝试了Fluent API 2,但没有满足要求。每当有插入或更新时,它都会更新该列的所有行。

   modelbuilder.Entity<Author>().Property(a => a.UpdatedAt).HasComputedColumnSql("GetUtcDate()");

c# entity-framework ef-fluent-api
1个回答
0
投票

我不是 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
© www.soinside.com 2019 - 2024. All rights reserved.