2013-05-16 28 views
7

Tôi hiện đang làm việc trên một dự án web n-tier. Sau khi nghiên cứu về các đối tượng chuyển dữ liệu và lợi ích của chúng, chúng tôi đã quyết định đưa mẫu này đi. Trang web ASP.NET MVC của chúng tôi không có quyền truy cập trực tiếp vào EF DbContext nhưng thay vào đó sẽ sử dụng DTO để gửi và nhận dữ liệu thực thể. Sẽ có một lớp dịch vụ/ánh xạ sẽ chuyển đổi giữa các DTO và các mô hình thực thể.Dịch các thuộc tính điều hướng mô hình Khung thực thể thành DTOs

Câu hỏi của tôi là, cách tốt nhất để dịch thuộc tính điều hướng mô hình thực thể thành DTO của nó là gì?

Dưới đây là một ví dụ về một mô hình tổ chức và DTO từ dự án:

Entity Mẫu:

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

Nhû coá thïí thêëy chúng rất giống nhau ngoại trừ các thuộc tính điều hướng. Tôi đã thay đổi chúng để giữ các số nguyên Id (của các thực thể) thay vì các mô hình thực thể. Do đó, nếu các thực thể thuộc tính điều hướng cần được lấy, Id của chúng có thể được chuyển vào chức năng lớp dịch vụ/ánh xạ sẽ truy xuất các thực thể từ cơ sở dữ liệu, ánh xạ chúng tới DTO và trả về bộ sưu tập. Đây có phải là cách làm việc có thể chấp nhận được không?

Tôi mới đến khu vực này vì vậy một số thuật ngữ của tôi có thể không hoàn toàn chính xác nhưng hy vọng bạn sẽ hiểu những gì tôi đang nhận được. Nếu bạn cần tôi làm rõ hoặc cung cấp thêm chi tiết về bất cứ điều gì, xin vui lòng cho tôi biết.

Trả lời

12

Bạn có thể tải các DTOs sử dụng một chiếu:

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

Bạn phải khai báo các OrderIds trong dto như IEnumerable<int> Mặc dù vậy, không phải là ICollection<int> để làm biên dịch này.

Tôi không chắc liệu bộ sưu tập khóa này có thực sự hữu ích hay không. Nếu bạn muốn tải các đơn đặt hàng sau bạn có thể làm điều đó trong một phương pháp dịch vụ riêng biệt chỉ dựa trên ID của Payment, như vậy:

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

Cám ơn câu trả lời của bạn, tôi đánh giá cao thời gian của bạn. Tôi sẽ cung cấp cho bạn một cuộc bỏ phiếu nhưng tôi không có đủ đại diện! Ví dụ về phép chiếu này khác với thư viện ánh xạ như AutoMapper như thế nào? Tôi biết chính xác những gì bạn muốn nói về các bộ sưu tập chính, nhưng đó là cách giữ một tham chiếu đến các mối quan hệ thực thể. Tôi cho rằng không phải lúc nào cũng cần thiết nhưng nó có thể hữu ích cho một số DTO. –

+0

@ChrisWhite: Sử dụng AutoMapper sẽ buộc bạn tải thực thể 'Thanh toán' bao gồm tất cả' Đơn hàng' đầu tiên từ DB (với tất cả các cột theo thứ tự), sau đó áp dụng AutoMapper mà sẽ bỏ qua hầu hết các thuộc tính đã tải vì bộ sưu tập của bạn trong dto chỉ chứa 'int'. Điều này có thể là rất nhiều chi phí truy vấn. Phép chiếu ở trên được thực hiện hoàn toàn trong cơ sở dữ liệu và chỉ trả về các cột được yêu cầu trong phép chiếu. – Slauma

Các vấn đề liên quan