2015-12-01 16 views
6

Tôi đang cố gắng tìm ra các phương pháp hay nhất khi cập nhật thực thể và tất cả là con của nó. Ví dụ; Tôi có dịch vụ cập nhật "Nhà tuyển dụng" sẽ cập nhật pháp nhân của chủ lao động và các thực thể "Địa chỉ" của chủ sử dụng lao động và các thực thể "Điện thoại" của từng "Địa chỉ". Người dùng có thể thêm địa chỉ mới cho chủ nhân hiện tại hoặc họ có thể cập nhật địa chỉ hiện tại hoặc họ có thể xóa một số địa chỉ, cùng áp dụng cho điện thoại của từng địa chỉ. Bạn có thể giúp tôi viết mã lý tưởng có thể xử lý kịch bản này không.EF7 Cách xử lý thao tác cập nhật cho các thực thể lồng nhau

Tôi đang sử dụng EF7 rc1 và tôi sử dụng Automapper để ánh xạ Dto to Entity trong dịch vụ của tôi.

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

Phương thức dịch vụ của tôi;

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

Trả lời

0

Ví dụ này giống như một cách phù hợp để xử lý các bộ sưu tập con. Mỗi bộ sưu tập phải được kiểm tra thủ công để thực hiện hành động. (Sử dụng Generics âm thanh tốt, nhưng lúc nào cũng cắn lại một cách nào đó Thông thường, hiệu suất..)

Với ý nghĩ đó, đây là một vài khuyến nghị:

  • Move bộ sưu tập con xử lý vào phương pháp riêng biệt/dịch vụ.
  • Nếu truy vấn cho các thực thể hiện có, hãy truy lục toàn bộ bộ sưu tập trong một truy vấn rồi lặp lại kết quả trong bộ nhớ.
  • Vì bạn đang viết mã không đồng bộ, bạn có thể tận dụng lợi thế của việc xử lý các bộ sưu tập con song song! Để làm điều này, mỗi thao tác phải tạo ra bối cảnh riêng của nó. This explains why it's faster.

Dưới đây là một ví dụ sử dụng các khuyến nghị:

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);  
    } 
} 
Các vấn đề liên quan