Ade*_*Tas 6 c# entity-framework entity-framework-core asp.net-core
我试图找出更新实体及其所有子实体时的最佳实践.例如; 我有一个"雇主"更新服务,它将更新雇主实体和雇主的"地址"实体以及每个"地址"的"电话"实体.用户可以向现有雇主添加新地址,或者他们可以更新当前地址,或者他们可以删除一些地址,同样适用于每个地址的电话.你能帮我写出处理这种情况的理想代码吗?
我正在使用EF7 rc1,我使用Automapper将Dto映射到我的服务中的实体.
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; }
}
Run Code Online (Sandbox Code Playgroud)
我的服务方式;
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个例子看起来是处理子集合的好方法。必须手动检查每个集合所执行的操作。(使用泛型听起来不错,但总是会以某种方式产生负面影响。通常是性能。)
考虑到这一点,这里有一些建议:
以下是使用建议的示例:
private async Task UpdateAddresses(List<Address> addressesToUpdate)
{
using(var context = new Context())
{
var existingAddressIds = await context.Addresses
.Where(a => addressesToUpdate.Contains(a.AddressId))
.ToListAsync()
.ConfigureAwait(false);
existingAddressIds.ForEach(a => context.Addresses.Remove(a));
await context.SaveChangesAsync().ConfigureAwait(false);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |