如何在数据库事务中存储当前用户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
相关产品推荐
相关产品推荐

