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

如何在数据库事务中存储当前用户ID作为Created By与Updated By?

实现记录创建/更新用户ID的方案

1. 扩展基类模型

先在BaseModel中添加存储用户ID的字段,默认ASP.NET Identity的用户ID为string类型,字段定义如下:

namespace Core.Models
{
    public class BaseModel : ConfigurationBaseModel
    {
        public DateTime CreatedAt { get; set; }
        public DateTime? UpdatedAt { get; set; }
        public string CreatedBy { get; set; }
        public string? UpdatedBy { get; set; }
    }
}

2. 注入HttpContext访问器到DbContext

要获取当前登录用户的ID,需借助IHttpContextAccessor访问请求上下文。首先在DbContext的构造函数中注入该服务:

using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;

public class YourDbContext : DbContext
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public YourDbContext(DbContextOptions<YourDbContext> options, IHttpContextAccessor httpContextAccessor)
        : base(options)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    // 此处添加你的DbSet定义及其他配置
}

同时要在Program.cs中注册IHttpContextAccessor服务:

builder.Services.AddHttpContextAccessor();

3. 更新SaveChangesAsync方法

修改之前重写的保存逻辑,在处理实体新增和修改状态时,设置对应的创建人/更新人ID:

public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
    var now = DateTime.UtcNow;
    // 从HttpContext中获取当前用户ID,未认证时使用默认标识
    var currentUserId = _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier) ?? "system";

    foreach (var changedEntity in ChangeTracker.Entries())
    {
        if (changedEntity.Entity is BaseModel entity)
        {
            switch (changedEntity.State)
            {
                case EntityState.Added:
                    entity.CreatedAt = now;
                    entity.UpdatedAt = null;
                    entity.CreatedBy = currentUserId;
                    entity.UpdatedBy = null;
                    break;
                case EntityState.Modified:
                    // 禁止修改创建时间和创建人
                    Entry(entity).Property(x => x.CreatedAt).IsModified = false;
                    Entry(entity).Property(x => x.CreatedBy).IsModified = false;
                    entity.UpdatedAt = now;
                    entity.UpdatedBy = currentUserId;
                    break;
            }
        }
    }

    return base.SaveChangesAsync(cancellationToken);
}

额外注意点

  • 若存在后台任务、批量数据导入或种子数据初始化等无HttpContext的场景,currentUserId会使用默认的"system"标识,可根据业务需求调整该默认值。
  • 如果系统使用的用户ID不是string类型(比如int),请对应修改CreatedBy和UpdatedBy的字段类型,并调整获取用户ID的代码。
  • 确保IHttpContextAccessor已正确注册,否则会引发空引用异常。

内容的提问来源于stack exchange,提问作者Mohamed Ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:05:29