【问题标题】:Error on inserting entity just by updating aggregate root仅通过更新聚合根插入实体时出错
【发布时间】:2021-06-12 22:30:47
【问题描述】:

我已经定义了实体应用程序,它也是根聚合,它的孩子是角色。我遵循您应该只为聚合根定义存储库的规则,并且在尝试将新角色插入数据库时​​遇到了问题。

我的应用程序中的场景:

internal void AddRole(string name, string code, string description, bool isSystemic)
{
    Roles.Add(RoleFactory.Create(name, code, description, isSystemic, Id));
}

此操作创建新的角色实体并将其添加到应用程序角色集合中。

现在我想在我的存储库上调用SaveChanges 并插入新创建的实体,为此我在我的域服务中使用以下代码:

public async Task AddRoleAsync(
        Guid applicationId,
        string name,
        string code,
        string description,
        bool isSystemic,
        CancellationToken cancellationToken)
{
    var application = await _applicationRepository.GetAsync(applicationId, false, true, cancellationToken)
            ?? throw new Exception();

    application.AddRole(name, code, description, isSystemic);
    _applicationRepository.Update(application);
    await _applicationRepository.SaveChangesAsync();
}

我收到一个错误:

数据库操作预计会影响 1 行,但实际上会影响 0 行。自加载实体以来,数据可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=527962

我已尝试点击此链接,但没有找到对我的案例有意义的信息。我是唯一使用数据库的人,所以在我的操作过程中其他人没有机会编辑/删除数据。

在正常情况下,我会在RoleRepository 中调用AddAsync,但正如我上面所说,我真的不想为聚合根以外的实体创建存储库。我是 DDD 的新手,因此我们将不胜感激。

编辑:我决定提供有关ApplicationRepository 的更多信息。代码如下:

public async Task SaveChangesAsync()
{
        var potentiallyAffectedEntities = await DbContext.GetAffectedTrackedEntitiesAsync();

        await DbContext.SaveChangesAsync(); // Exception occurs here

        await DbContext.DispatchDomainEventsAsync(DomainEventPublisher, potentiallyAffectedEntities);
}

public void Update(TAggregateRoot aggregateRoot)
        => DbContext
            .Set<TAggregateRoot>()
            .Update(aggregateRoot);

出于调试目的,我将此代码添加到我的存储库中:

var potentiallyAffectedEntities = await DbContext.GetAffectedTrackedEntitiesAsync();
        potentiallyAffectedEntities.Skip(1)
            .FirstOrDefault() // This gets new role entity
            .State = EntityState.Added;

此代码通过没有任何问题,所以我认为问题是 EF 将 EntityState 设置为 Modified 而不是 Added。现在的问题是如何强制它以另一种方式执行?

【问题讨论】:

  • 您需要共享您的存储库实现。
  • 是的,我现在才意识到。我编辑了帖子
  • 打开 EF 跟踪,查看它向数据库发送的命令以及报告零行受到影响的原因。

标签: c# entity-framework domain-driven-design root


【解决方案1】:

好的,我终于找到了解释,问题是我在代码中生成了 RoleId (Guid),因此 Entity 的框架方法更新将其条目标记为已修改。解决方案是分配 Guid.Empty 并让数据库生成它。这解决了问题,因为 ef 现在正确地将条目状态设置为已添加。 所以我工厂里的代码现在是这样的:

internal static Entities.Role Create(string name, string code, string description, bool isSystemic, Guid applicationId)
        => new(
            Guid.Empty,
            name,
            code,
            description,
            isSystemic,
            applicationId);

希望它可以帮助某人:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    相关资源
    最近更新 更多