繁体   English   中英

EF Core 在父实体保存时更新子实体

[英]EF Core upsert child entities upon parent entity save

我有一个 DDD 聚合,其中 User 作为根,Appointment 作为子记录。 我想,当我在我的存储库中保存一个用户时,更新该用户的现有子约会并插入数据库中不存在的子约会。

我为每个实体都有一个域 class 和一个持久性 class

我已经阅读了这篇关于此事的帖子,我想我理解接受的答案解释了什么,所以我遵循以下逻辑:

    public async Task Update(IApplicationUserWithAppointments domainUserEntity)
    {
        ApplicationUserEntity persistenceUserEntity = await FindEntityById(domainUserEntity.Id);

        IDictionary<Guid, AppointmentEntity> appointmentEntitiesById =
            persistenceUserEntity.Appointments
                .ToDictionary(appointmentEntity => appointmentEntity.Id, appointmentEntity => appointmentEntity);

        persistenceUserEntity.UserName = domainUserEntity.UserName;
        persistenceUserEntity.Password = domainUserEntity.Password;
        persistenceUserEntity.FirstName = domainUserEntity.FirstName;
        persistenceUserEntity.LastName = domainUserEntity.LastName;
        persistenceUserEntity.Role = domainUserEntity.Role;
        persistenceUserEntity.Validated = domainUserEntity.Validated;
        persistenceUserEntity.Appointments = domainUserEntity.Appointments
            .Select(appointment => BuildOrUpdateAppointmentEntity(appointmentEntitiesById, appointment))
            .ToList();

        this.context.Users.Update(persistenceUserEntity);
    }

    private static AppointmentEntity BuildOrUpdateAppointmentEntity(IDictionary<Guid, AppointmentEntity> appointmentEntitiesById,
        Appointment appointment)
    {
        if (!appointmentEntitiesById.ContainsKey(appointment.Id))
        {
            return new AppointmentEntity(appointment);
        }

        AppointmentEntity appointmentEntity = appointmentEntitiesById[appointment.Id];
        appointmentEntity.State = appointment.State.Name;
        appointmentEntity.DateTime = appointment.DateTime;
        return appointmentEntity;
    }

逻辑是我从数据库中检索用户实体及其约会(以避免分离实体错误)。 然后,我 map 约会实体,更新现有实体并创建新实体。

此逻辑适用于更新现有约会记录,但对于插入新约会记录,以下单元测试失败:

    public async Task Update_ChildRecord_InsertChildRecordInDb()
    {
        // Given
        ApplicationUserEntity entity = await this.dbDataFactory.InsertValidatedLifeAssistant();
        var repository = new ApplicationUserRepository(this.context, factory);

        entity.Appointments.Add(new AppointmentEntity()
        {
            Id = Guid.NewGuid(),
            State = "Planned",
            DateTime = DateTime.Today.AddDays(3)
        });
        
        // When
        await repository.Update(entity.ToDomainEntity(new AppointmentStateFactory()));
        await repository.Save();

        // Then
        entity = await this.context
            .Users
            .Include(u => u.Appointments)
            .FirstAsync(item => item.Id == entity.Id);
        (await this.context.Appointments.CountAsync()).Should().Be(1);
    }

出现以下错误:

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

在更新的Save调用上。

我不明白为什么我的逻辑不起作用。 先感谢您

经过大量调试,并感谢 github 的帖子,我意识到我的问题是我的子记录已经生成了一个 ID,而 EF Core 并没有预料到它。 我通过在onModelCreating model 定义中使用ValueGeneratedNever()解决了我的问题。 前任:

        modelBuilder.Entity<AppointmentEntity>().HasKey(appointment => appointment.Id);
        modelBuilder.Entity<AppointmentEntity>().Property(appointment => appointment.Id).ValueGeneratedNever();
        modelBuilder.Entity<AppointmentEntity>().Property(appointment => appointment.State);
        modelBuilder.Entity<AppointmentEntity>().Property(appointment => appointment.DateTime);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM