2015-12-01 10 views
6

Bir varlığı ve tüm çocukları olan çocukları güncelleştirirken en iyi uygulamaları bulmaya çalışıyorum. Örneğin; İşveren varlığını ve işverenin "Adres" varlıklarını ve her "Adres" in "Telefon" varlıklarını güncelleyen bir "İşveren" güncelleme hizmetim var. Kullanıcı mevcut işverene yeni adresler ekleyebilir veya mevcut adresleri güncelleyebilir veya her bir telefonun telefonları için aynı olanları da silebilir. Bu senaryoyu ele alacak ideal kodu yazmam için bana yardımcı olabilir misiniz?EF7 Yuvalanmış varlıklar için güncelleştirme işleminin nasıl gerçekleştirileceği

EF7 rc1 kullanıyorum ve Servisimde Dto'yu Varlık ile eşlemek için Automapper'ı kullanıyorum.

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

Servis yöntemim;

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

cevap

0

Bu örnek, çocuk koleksiyonlarını işlemek için iyi bir yol gibi görünüyor. Her koleksiyon, gerçekleştirilen eylem için manuel olarak kontrol edilmelidir. (Jenerikler kullanarak iyi geliyor, ama her zaman geri bir şekilde ısırır Tipik olarak, performansı..) Göz önüne aldığımızda

, burada birkaç tavsiyeler var:

  • Taşı ayrı yöntemler/hizmetler içine işleme çocuk koleksiyonu.
  • Mevcut varlıklar için sorgulama yapıyorsanız, tüm koleksiyonu bir sorguya alın ve sonuçları bellekte yineleyin.
  • Eşzamansız kod yazdığınız için, çocuk koleksiyonlarını paralel olarak işlemekten faydalanabilirsiniz! Bunu yapmak için, her işlem kendi bağlamını oluşturmalıdır.

    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);  
        } 
    } 
    
    : This explains why it's faster.

İşte öneriler kullanıldığı bir örnek

İlgili konular