[英]Translating Entity Framework model navigation properties into DTOs
我目前正在開發一個n層Web項目。 在研究了數據傳輸對象及其優點之后,我們決定采用這種模式。 我們的ASP.NET MVC網站無法直接訪問EF DbContext,而是使用DTO發送和接收實體數據。 將有一個服務/映射層將在DTO和實體模型之間進行轉換。
我的問題是,將實體模型導航屬性轉換為DTO的最佳方法是什么?
以下是項目中實體模型及其DTO的示例:
實體模型:
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; }
}
可以看出,除導航屬性外,它們非常相似。 我已將它們更改為保存整數ID(實體),而不是實體模型。 因此,如果需要獲取導航屬性實體,則它們的Id可以傳遞到服務/映射層函數,該函數將從當時數據庫中檢索實體,將它們映射到DTO並返回集合。 這是一種可接受的做事方式嗎?
我是這個領域的新手,所以我的一些術語可能不完全正確,但希望你能理解我所得到的。 如果您需要我澄清或提供任何其他詳細信息,請告訴我。
您可以使用投影加載DTO:
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();
您必須將dto中的OrderIds
聲明為IEnumerable<int>
,而不是ICollection<int>
來進行此編譯。
我不確定這個密鑰集合是否真的有用。 如果您想稍后加載訂單,您可以根據Payment
的ID
在單獨的服務方法中執行此操作,如下所示:
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();
}
我通常在這種情況下使用Automapper。 我將創建一個Dto類形成我的主要實體,並為我的導航屬性實體創建Dto,然后讓Automapper自動執行映射,而無需手動編寫映射代碼。
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
public virtual PaymentMechanismDto PaymentMechanism { get; set; }
public virtual ICollection<OrderDto> Orders { get; set; }
}
public class PaymentMechanismDto
{
//properties
}
public class OrderDto
{
//properties
}
public class MappingProfile : Profile
{
public MappingProfile()
{
Mapper.CreateMap< Payment, PaymentDto >();
Mapper.CreateMap< PaymentMechanism, PaymentMechanismDto >();
Mapper.CreateMap< Order, OrderDto >();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.