簡體   English   中英

EF7如何處理嵌套實體的更新操作

[英]EF7 How to handle the update operation for nested entities

我試圖找出更新實體及其所有子實體時的最佳實踐。 例如; 我有一個“雇主”更新服務,它將更新雇主實體和雇主的“地址”實體以及每個“地址”的“電話”實體。 用戶可以向現有雇主添加新地址,或者他們可以更新當前地址,或者他們可以刪除一些地址,同樣適用於每個地址的電話。 你能幫我寫出處理這種情況的理想代碼嗎?

我正在使用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; }
}

我的服務方式;

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);
            }
        }
 }

這個例子看起來像處理子集合的好方法。 必須手動檢查每個集合以執行所執行的操作。 (使用泛型聽起來不錯,但總是以某種方式咬回來。通常,性能。)

考慮到這一點,這里有一些建議:

  • 將子集合處理移動到單獨的方法/服務中。
  • 如果查詢現有實體,則在一個查詢中檢索整個集合,然后在內存中迭代結果。
  • 由於您正在編寫異步代碼,因此您可以利用並行處理子集合! 為此,每個操作都應創建自己的上下文。 這解釋了為什么它更快。

以下是使用建議的示例:

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);    
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM