如何使用Automapper投影到子实体

问题描述 投票:0回答:1

我有以下实体类

public class Customer
{
    public long Id { get; set; }
    [StringLength(100)]
    public string Name { get; set; } = string.Empty;
    [StringLength(254)]
    public string? Email { get; set; }
    public List<Order> Orders { get; set; } = new List<Order>();
}

public class Order
{
    public long Id { get; set; }
    public long CustomerId { get; set; }
    [ForeignKey(nameof(CustomerId))]
    public Customer? Customer { get; set; }
    public DateOnly Date { get; set; }
    public List<OrderLine> Lines { get; set; } = [];
}

public class OrderLine
{
    public long Id { get; set; }
    public long OrderId { get; set; }
    [ForeignKey(nameof(OrderId))]
    public Order? Order { get; set; }
    [StringLength(100)]
    public string Item { get; set; } = string.Empty;
    public decimal Amount { get; set; }
}

并且,还有相应的数据传输对象(DTO):

public class CustomerDto
{
    public long Id { get; set; }
    public string Name { get; set; } = string.Empty;
}

public class OrderDto
{
    public long Id { get; set; }
    public long CustomerId { get; set; }
    public CustomerDto? Customer { get; set; }
    public DateOnly Date { get; set; }
    public List<OrderLineDto> Lines { get; set; } = [];
}

public class OrderLineDto
{
    public long Id { get; set; }
    public long OrderId { get; set; }
    public string Item { get; set; } = string.Empty;
    public decimal Amount { get; set; }
}

我做了以下 AutoMapper 配置:

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Customer, CustomerDto>()
            .ReverseMap()
            .ForPath(o => o.Id, o => o.Ignore());
        CreateMap<Order, OrderDto>()
            .ReverseMap()
            .ForPath(o => o.Id, o => o.Ignore());
        CreateMap<OrderLine, OrderLineDto>()
            .ReverseMap()
            .ForPath(o => o.Id, o => o.Ignore());
    }
}

以上配置已注册到我的 ASP.NET Web 应用程序的 DI 中:

services.AddAutoMapper(typeof(AutoMapperProfile));

现在,我想使用特定搜索条件搜索 Orders 实体,并将其映射到 OrderDto 并发送到我的 Web 客户端。为此,我执行以下操作:

var config = new MapperConfiguration(cfg => cfg.CreateProjection<Order, OrderDto>());
IQueryable<Order> query = db.Orders
    .Include(o => o.Customer)
    .Include(o => o.Lines);

// Apply some Where criteria here

var orderDtos = await query
    .AsNoTracking()
    .OrderBy(o => o.Id)
    .ProjectTo<OrderDto>(config)
    .ToListAsync();

但是,我收到以下错误:

Unable to create a map expression from Order.Customer to CustomerDto.Customer ...

我猜 OrderLineDto 也存在类似的问题,尽管错误消息尚未说明任何相关信息。我可以解决这个问题吗?看来我应该使用 ForMember 方法编辑我的配置,但我无法使其工作。

asp.net-core entity-framework-core automapper
1个回答
0
投票

您的映射配置的初始化有点可疑。如果您使用的是 Automapper 配置文件,请尝试以下操作:

var config = new MapperConfiguration(cfg => cfg.AddProfile(new AutoMapperProfile());
var orderDtos = await db.Orders
    .OrderBy(o => o.Id)
    .ProjectTo<OrderDto>(config)
    .ToListAsync();

请注意,使用投影时,您不需要急切加载相关实体(

Include
)或担心跟踪。 (
AsNoTracking
)。不会填充或跟踪任何实体,EF 将根据映射的投影自动连接必要的表。

© www.soinside.com 2019 - 2024. All rights reserved.