首页 > 解决方案 > dbContext 不会更新

问题描述

我有一个命令类作为 CQRS 工作流的一部分。它插入并更新几个不同的表,如下所示:

public class ClassName : IBusinessCommand<CommandRequest, CommandResult>

private readonly DatabaseContext _dbContext;

public ClassName(DatabaseContext dbContext)
{
    _dbContext = dbContext;
}


public async Task<CommandResult> ExecuteAsync(CommandRequest request, CancellationToken token)
{
    var user = _dbContext.Users.NoTracking()
        .Where(x => x.request.UserId);

    if (user != null)
    {
        var class = new Class
        {
             ClassID = 1,
             UserID = user.UserID,
             CreateDate = _clock.UtcNow
        }

        _dbContext.Classes.Add(class);
    }

    var seat = await FunctionThatGetsSeatRecord(token);

    seat.ModifyDate = _clock.UtcNow;
    seat.SeatsUsed++;
    seat.SeatsRemaining--

    return CommandResult.WithSuccess();
}

我们有一个名为 CommandRunner 的基类(用于我们所有的类似命令)。在这个基类中,它调用 ExecuteAsync 函数(对于传入的任何类型参数),如下所示:

var command = _container.Resolve<IBusinessCommand<TData, TResult>>(
    new TypedParameter(typeof(IHoneyBeeDbContext), dbContext));
                    
var result = await command.ExecuteAsync(data, token);
await dbContext.SaveChangesAsync();
transaction.Commit();

以便对该命令 dbContext 所做的所有更改都保存并作为单个事务提交。我们已经为我们的 CQRS 安装了同样的基础设施一段时间了,它运行得非常好。上面的类以前在不同的服务类中,我决定将它转换为我们的 CQRS 流,所以我把它变成了一个命令。由于我无法弄清楚的原因(我已经考虑了几个小时),我可以让创建的类正确添加到数据库中,但我无法更新座位记录。我已经调试了整个类,并在整个流程中跟踪并检查了 _dbContext 变量,并且更新在其中正确显示,但是当它被保存和提交时,它不会为那个变量更新数据库(但它确实适用于类)。

标签: c#.netentity-frameworklinq-to-entities

解决方案


您指出返回座位的函数使用 NoTracking()(AsNoTracking() 的错字?),它会关闭更改跟踪,因此 EF 对您对座位所做的更改视而不见。

不要在您计划查询、更新和保存实体的集合上使用“无跟踪”

(在某些 EF 版本或情况下使用它可能根本不会带来任何好处,请参阅https://github.com/dotnet/efcore/issues/14366

未跟踪实体的详细信息:.AsNoTracking() 有何不同?


推荐阅读