I am trying to figure out the best practices when updating an entity and all it's children. For example; I have an "Employer" update service that would update the employer entity and the "Address" entities of the employer and the "Phone" entities of each "Address". User may add new addresses to the existing employer or they may update the current addresses or they can delete some, same applies for the phones of each addresses. Could you help me to write the ideal code that would handle this scenario.
I am using EF7 rc1 and I use Automapper to map the Dto to Entity in my service.
public partial class Employer
{
public int EmployerId { get; set; }
public int Name { get; set; }
[InverseProperty("Employer")]
public virtual ICollection<Address> Address { get; set; }
}
public partial class Address
{
public int AddressId { get; set; }
public int Address1{ get; set; }
public int City { get; set; }
[ForeignKey("EmployerId")]
[InverseProperty("Address")]
public virtual Employer Employer { get; set; }
[InverseProperty("Address")]
public virtual ICollection<Phone> Phone { get; set; }
}
public partial class Phone
{
public int PhoneId { get; set; }
public string Number { get; set; }
[ForeignKey("AddressId")]
[InverseProperty("Phone")]
public virtual Address Address { get; set; }
}
My service method;
public async Task<IServiceResult> Update(EmployerDto employer)
{
var employerDbEntity = await _db.Employer
.Include(a=>a.Address).ThenInclude(p=>p.Phone)
.SingleOrDefaultAsync (a=>a.EmployerId == employer.EmployerId);
//How to handle the update operation for children?
var entity = Mapper.Map<Employer>(employer);
HandleChildren(employerDbEntity,entity);
await _db.SaveChangesAsync();
...
...
}
private void HandleChildren(Employer employerDbEntity,Employer entity)
{
//Delete
foreach (var existing in employerDbEntity.Address.ToList())
{
if (!entity.Address.Any(a => a.AddressId == existing.AddressId))
employerDbEntity.Address.Remove(existing);
}
//Update or Insert
foreach (var address in entity.Address)
{
var existing = employerDbEntity.Address.SingleOrDefault(a =>a.AddressId == address.AddressId);
//Insert
if (existing == null)
{
employerDbEntity.Address.Add(address);
}
//Update
else
{
Mapper.Map(address, existing);
}
}
}