![](/img/trans.png)
[英]EF Core: Can add and save parent entity, but fail to save child entities at all
[英]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.