2013-05-16 17 views
7

Attualmente sto lavorando a un progetto Web di livello superiore. Dopo aver ricercato gli oggetti Data Transfer e i loro benefici, abbiamo deciso di dare questo schema. Il nostro sito Web ASP.NET MVC non ha accesso diretto a EF DbContext ma utilizzerà invece DTO per inviare e ricevere dati di entità. Ci sarà un livello servizio/mappatura che convertirà tra DTO e modelli di entità.Conversione delle proprietà di navigazione del modello Entity Framework in DTO

La mia domanda è, qual è il modo migliore per tradurre le proprietà di navigazione del modello di entità nel suo DTO?

Di seguito è un esempio di un modello di entità e la sua DTO dal progetto:

Entity Modello:

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:

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

Come si può vedere sono molto simili ad eccezione delle proprietà di navigazione. Li ho modificati per contenere gli ID interi (delle entità) anziché i modelli di entità. Pertanto, se è necessario ottenere le entità della proprietà di navigazione, i relativi ID possono essere passati a una funzione di livello servizio/mappatura che recupererà le entità dal database, le associerà a DTO e restituirà la raccolta. È un modo accettabile di fare le cose?

Sono nuovo in quest'area, quindi una parte della mia terminologia potrebbe non essere completamente corretta, ma si spera che capirai cosa sto ottenendo. Se hai bisogno di me per chiarire o fornire ulteriori dettagli su qualsiasi cosa, per favore fatemelo sapere.

risposta

12

È possibile caricare i DTOs utilizzando una proiezione:

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

si deve dichiarare il OrderIds nella dto come IEnumerable<int> però, non come ICollection<int> per rendere questa compilazione.

Non sono sicuro che questa raccolta di chiavi sia davvero utile. Se si desidera caricare gli ordini in seguito si potrebbe fare in un metodo di servizio separato solo in base alla ID del Payment, in questo modo:

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

Grazie per la risposta, Apprezzo il vostro tempo. Ti darei un voto alto ma non ho abbastanza rep! In che modo questo esempio di proiezione differisce da una libreria di mapping come AutoMapper? So esattamente cosa intendi per le raccolte di chiavi, ma è un modo per mantenere un riferimento alle relazioni tra entità. Suppongo che non sia sempre necessario ma potrebbe rivelarsi utile per alcuni DTO. –

+0

@ChrisWhite: l'uso di AutoMapper ti costringerà a caricare l'entità "Pagamento" includendo tutti gli "Ordini" prima dal DB (con tutte le colonne di ordine), quindi applica AutoMapper che ignorerà la maggior parte delle proprietà caricate perché la tua raccolta nella Dto contiene solo un 'int'. Questo potrebbe essere un sovraccarico di query. La proiezione di cui sopra viene eseguita completamente nel database e restituisce solo le colonne richieste nella proiezione. – Slauma

Problemi correlati