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

ASP.NET Core 6.0 Web API:EF Core延迟加载代理下无法更新数据库

问题:EF Core 6.0 创建用户时数据库不更新但能正常查询

环境与配置

使用EF Core 6.0延迟加载功能,已安装Microsoft.EntityFrameworkCore.Proxies包,DbContext配置如下:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        optionsBuilder.UseLazyLoadingProxies().UseSqlServer("Server = SRV84; Database = BASE_DEMO1; User Id = sa; Password = Ab@123456");
    }
}

API核心代码

创建用户接口(POST)

[HttpPost]
public async Task<IActionResult> CreateUser(UserCreateDto oUserCreate)
{
    var oUser = await _authorizationService.GetUserByUserName(oUserCreate.Username);

    if (oUser.Id > 0)
    {
        return BadRequest("Username already exists");
    }

    oUserCreate.Status = (int)StatusUser.Deactive;
    oUserCreate.CreatedDate = DateTime.Now;
    oUserCreate.ModifiedDate = DateTime.Now;
    oUserCreate.Status = (int)StatusUser.Deactive;

    var idUser = await _authorizationService.CreateUser(oUserCreate);

    if (idUser == 0)
    {
        await AddLogAsync(UserIdentity.FullName + ": create " + oUserCreate.FullName, OBJECT.USERS, (int)ActionLogs.Add, (int)StatusLogs.Error);
        return BadRequest("There was an error!");
    }

    await AddLogAsync(UserIdentity.FullName + ": create " + oUserCreate.FullName, OBJECT.USERS, (int)ActionLogs.Add, (int)StatusLogs.Success);

    #region Create new Userinfo   
    UserInfoCreateDto userInfo = new UserInfoCreateDto();
    userInfo.Address = oUserCreate.Address;
    userInfo.Email = oUserCreate.Email;
    userInfo.Avatar = oUserCreate.Avatar;
    userInfo.Phone = oUserCreate.PhoneNumber;
    userInfo.Sex = oUserCreate.Sex;
    userInfo.UserId = idUser;

    await BaseService.CreateAsync<UserDetail, UserInfoCreateDto>(userInfo);
    #endregion

    #region Create new Group   
    if (oUserCreate.GroupIds.Count > 0)
    {
        foreach (var item in oUserCreate.GroupIds)
        {
            if (item > 0)
            {
                await BaseService.CreateAsync<GroupUser, GroupUserCreateDto>(new GroupUserCreateDto() { GroupId = item, UserId = idUser });
            }
        }
    }
    #endregion

    return Ok();
}

查询用户接口(GET)

[HttpGet]
public async Task<IActionResult> GetUsers([FromQuery] UserGridPagingDto pagingModel)
{
    var predicates = pagingModel.GetPredicates();
    var result = await BaseService.FilterPagedAsync<User, UserGridDto>(pagingModel, predicates.ToArray());

    if (pagingModel.GroupId > 0)
    {
        if (result.Data.Count > 0)
        {
            for (int i = 0; i < result.Data.Count; i++)
            {
                result.Data[i].IsCheck = result.Data[i].LstGroupIds.Contains(pagingModel.GroupId);
            }
        }
    }

    return Ok(result);
}

问题现象

调用POST接口创建用户时,数据库无任何更新,但GET接口能正常返回之前添加的旧数据;尝试删除数据库、注释连接字符串并重启电脑后,仍能获取到旧数据。

终端日志输出

16' with options: using lazy loading proxies
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (52ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT COUNT(*)
      FROM [Users] AS [u]
      WHERE [u].[DeletedUserId] IS NULL
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (52ms) [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
      SELECT [t].[Id], [t].[UserName], [t].[FullName], [t].[c], [t].[Status], [t].[CreatedDate], [t].[DeletedUserId], [t].[c0], [g].[GroupId], [g].[Id]
      FROM (
          SELECT TOP(@__p_0) [u].[Id], [u].[UserName], [u].[FullName], (
              SELECT TOP(1) [u0].[Email]
              FROM [UserDetail] AS [u0]
              WHERE [u].[Id] = [u0].[UserId]) AS [c], [u].[Status], [u].[CreatedDate], [u].[DeletedUserId], (
              SELECT TOP(1) [u1].[Phone]
              FROM [UserDetail] AS [u1]
              WHERE [u].[Id] = [u1].[UserId]) AS [c0]
          FROM [Users] AS [u]
          WHERE [u].[DeletedUserId] IS NULL
          ORDER BY [u].[Id] DESC
      ) AS [t]
      LEFT JOIN [GroupUser] AS [g] ON [t].[Id] = [g].[UserId]
      ORDER BY [t].[Id] DESC
解决方案
  • 检查服务层的保存操作:
    确认_authorizationService.CreateUser和BaseService.CreateAsync内部是否调用了await _context.SaveChangesAsync()。基础服务封装时若遗漏此步骤,实体仅会被添加到内存上下文,不会同步到数据库。
  • 验证连接字符串的有效性:
    删除数据库后仍能获取旧数据,说明程序可能连接到了其他数据库实例。可在OnConfiguring中添加日志输出当前连接字符串,或直接登录SQL Server查看BASE_DEMO1数据库的实时数据,确认是否真的没有写入。
  • 排查是否使用内存数据库:
    检查项目启动配置(如Program.cs),确认是否意外注册了内存数据库(UseInMemoryDatabase)。若使用内存数据库,所有操作仅在内存中进行,重启后数据不会持久化,但旧数据可能来自之前的内存缓存。
  • 检查事务与异常处理:
    确认创建用户、用户信息、用户组的操作是否在同一事务中,是否有异常被吞导致事务回滚。可打印idUser的值,以及后续CreateAsync的执行结果,排查是否有步骤失败。
  • 验证实体主键配置:
    检查User、UserDetail、GroupUser实体的主键是否正确配置为自增(如[Key]+[DatabaseGenerated(DatabaseGeneratedOption.Identity)])。若主键未正确配置,插入时无法生成有效ID,会导致关联数据无法写入,甚至整个插入操作失败。

内容的提问来源于stack exchange,提问作者Levi Ackerman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:54:53