You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让EF Core在Update/SaveChanges时获取CreatedAt字段值?

问题描述

我有如下模型:

class Client 
{
    public int id {get; set;}
    ...
    public DateTime CreatedAt {get; set;}
}

并进行了如下类型配置(其他字段为默认配置):

builder.Property(p => p.CreatedAt)
    .HasDefaultValueSql("now() at time zone 'utc'")
    .ValueGeneratedOnAdd()    
    .Metadata.SetAfterSaveBehavior(Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Ignore);

执行更新操作时,我不想提供CreatedAt值,希望它始终保持不变,因此API的PUT(更新)接口不接收CreatedAt参数。设置Metadata.SetAfterSaveBehavior是为了在更新时忽略CreatedAt字段,但SaveChanges()后该字段仍为null/默认值。

我希望能让EF Core在更新操作时获取CreatedAt字段的值,即使不更新它。我知道可以使用Reload()方法重新加载所有字段,但这会让一次更新操作执行两次数据库请求,而第二次请求只是为了获取CreatedAt字段值,这并不理想。

解决方案

方案1:更新前仅查询CreatedAt字段(轻量双请求)

在执行更新逻辑前,单独查询目标实体的CreatedAt值并赋值给待更新实体,这样EF Core跟踪实体时会保留该值,更新后实体的CreatedAt就是数据库中的真实值:

// 假设待更新实体为updatedClient
var existingCreatedAt = _context.Clients
    .Where(c => c.id == updatedClient.id)
    .Select(c => c.CreatedAt)
    .FirstOrDefault();

updatedClient.CreatedAt = existingCreatedAt;

_context.Update(updatedClient);
await _context.SaveChangesAsync();

该方案仅查询单个字段,比Reload()加载整个实体的性能开销更小。

方案2:使用数据库返回值实现单请求更新+获取(最优)

通过执行原生SQL更新语句,利用数据库的RETURNING语法(以PostgreSQL为例,SQL Server可使用OUTPUT语法),在更新完成后直接返回CreatedAt值,仅需一次数据库请求:

// 示例:更新Name字段并返回CreatedAt
var createdAt = await _context.Database.QuerySingleAsync<DateTime>(@"
    UPDATE Clients 
    SET Name = @p1
    WHERE id = @p0
    RETURNING CreatedAt;", 
    updatedClient.id, updatedClient.Name);

updatedClient.CreatedAt = createdAt;

这种方式既完成了更新操作,又获取到了最新的CreatedAt值,避免了额外的查询请求。

方案3:调整实体跟踪逻辑

如果待更新实体是通过EF Core上下文跟踪的(比如先查询再修改),可以标记CreatedAt字段为未修改,确保EF Core保留原始跟踪值:

// 先查询获取跟踪的实体
var client = await _context.Clients.FindAsync(updatedClient.id);
// 修改需要更新的字段
client.Name = updatedClient.Name;
// 明确标记CreatedAt无需修改(默认已跟踪原始值,此步骤可省略)
_context.Entry(client).Property(c => c.CreatedAt).IsModified = false;

await _context.SaveChangesAsync();

这种情况下,EF Core会保留查询时获取的CreatedAt值,更新后实体的该字段不会被重置。


内容的提问来源于stack exchange,提问作者Oleh Tymoshenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:52:25