簡體   English   中英

將實體框架模型導航屬性轉換為DTO

[英]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>來進行此編譯。

我不確定這個密鑰集合是否真的有用。 如果您想稍后加載訂單,您可以根據PaymentID在單獨的服務方法中執行此操作,如下所示:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM