2013-05-16 18 views
7

Şu anda n katmanlı bir web projesi üzerinde çalışıyorum. Veri Aktarımı Nesneleri ve onların faydalarını araştırdıktan sonra bu kalıba bir karar vermeye karar verdik. ASP.NET MVC web sitemizin EF DbContext'e doğrudan erişimi yoktur, bunun yerine varlık verilerini göndermek ve almak için DTO'ları kullanır. DTO'lar ve varlık modelleri arasında dönüşecek bir hizmet/haritalama katmanı olacaktır.Varlık Çerçeve modelinin gezinme özelliklerini DTO'lara çevirme

Benim sorum, varlık modeli gezinme özelliklerini DTO'ya dönüştürmenin en iyi yolu nedir?

public class PaymentDto 
{ 
    public int ID { get; set; } 
    public DateTime? PaidOn { get; set; } 
    public decimal Amount { get; set; } 
    public string Reference { get; set; } 

    //--------Navigation Properties - Object Ids-------- 
    public int PaymentMechanismId { get; set; } 
    public ICollection<int> OrderIds { get; set; } 
} 

olarak görülebilir:

Varlık Modeli:

public class Payment 
{ 
    public int ID { get; set; } 
    public DateTime? PaidOn { get; set; } 
    public decimal Amount { get; set; } 
    public string Reference { get; set; } 

    //Navigation Properties 
    public virtual PaymentMechanism PaymentMechanism { get; set; } 
    public virtual ICollection<Order> Orders { get; set; } 
} 

DTO Aşağıda

bir bir varlık modeli örneği ve projeden onun DTO olduğu Navigasyon özellikleri dışında çok benzerler. Varlık modelleri yerine tamsayı kimliklerini (varlıkların) tutmaları için onları değiştirdim. Bu nedenle, gezinme özelliği varlıklarının elde edilmesi gerekiyorsa, kimlikleri, varlıkları veritabanından alacak, DTO'lara eşleyecek ve koleksiyona geri dönecek bir hizmet/eşleme katmanı işlevine geçirilebilir. Bu işleri yapmanın kabul edilebilir bir yolu mu?

Bu bölgeye yeni geldim, böylece terminolojimin bir kısmı tamamen doğru olmayabilir ama umarım ne elde ettiğimi anlarsınız. Herhangi bir konuda herhangi bir detayı açıklığa kavuşturmak veya belirtmek için bana ihtiyacınız varsa lütfen bana bildirin.

cevap

12

Bir projeksiyon kullanılarak DTOs yükleyebilirsiniz:

var paymentDtos = context.Payments 
    .Where(p => p.Amount >= 1000m) // just an example filter 
    .Select(p => new PaymentDto 
    { 
     ID = p.ID, 
     PaidOn = p.PaidOn, 
     Amount = p.Amount, 
     Reference = p.Reference, 
     PaymentMechanismId = p.PaymentMechanism.ID, 
     OrderIds = p.Orders.Select(o => o.ID) 
    }) 
    .ToList(); 

Bu derleme yapmamayı ICollection<int> gibi olsa IEnumerable<int> olarak DTO içinde OrderIds beyan etmek zorunda.

Bu anahtar koleksiyonunun gerçekten yararlı olup olmadığından emin değilim. Daha sonra emir yüklemek istiyorsanız bunu gibi sadece Payment ait ID dayanan ayrı bir hizmet yönteminde yapabileceğini: Cevabınız için

public IEnumerable<OrderDto> GetPaymentOrders(int paymentID) 
{ 
    return context.Payments 
     .Where(p => p.ID == paymentID) 
     .Select(p => p.Orders.Select(o => new OrderDto 
     { 
      ID = o.ID, 
      //etc. mapping of more Order properties 
     })) 
     .SingleOrDefault(); 
} 
+0

sayesinde, vaktinizi teşekkür ederiz. Size bir oy verdim ama yeterli temsilcim yok! Bu yansıma örneği, AutoMapper gibi bir eşleme kitaplığından nasıl farklıdır? Anahtar koleksiyonları hakkında tam olarak ne demek istediğimi biliyorum, ancak varlık ilişkilerine bir başvuru tutmanın bir yoludur. Sanırım her zaman gerekli değil, ancak bazı DTO'lar için yararlı olabilir. –

+0

@ChrisWhite: AutoMapper'ın kullanılması, tüm "Siparişler" de dahil olmak üzere "Sipariş" öğesini DB'den (siparişin tüm sütunlarıyla birlikte) yüklemenizi zorlar, ardından yüklenen özelliklerin çoğunu yok sayarken AutoMapper uygulamasın. sadece bir "int" içerir. Bu, fazladan bir sorgu yükü olabilir. Yukarıdaki projeksiyon tamamen veritabanında yürütülür ve sadece projeksiyonda istenen sütunları döndürür. – Slauma

İlgili konular