带有entityFramework Automapper .Net Core的嵌套映射

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

这是我对实体框架的查询:

var transportlist = await _context.Set<Transport>()
       .Include(transport => transport.TransportState)
       .Select(transport =>
           new
           {
               Transport = _mapper.Map<TransportDto>(transport),
               TransportState = _mapper.Map<TransportStateForTransportDto>(transport.TransportState),
           }
        )
        .Take(limitNumber)
        .ToListAsync();

 return transportlist;

这是我的TransportDto:

public class TransportDto
{
    public int TransportId { get; set; }
    public TransportStateForTransportDto TransportState { get; set; }
    public bool Locked { get; set; }
}

这里是我的TransportStateForTransportDto:

public class TransportStateForTransportDto
{
    public string Label { get; set; }
}

我想得到类似的结果:

[
    {
        "transportId": 123456,
        "transportState" : {
            "Label": "Deleted"
        },
        "locked" : false
    }
]

但是,我有这个(这有点合逻辑...):

[
    {
        "transport": {
            "transportId": 123456,
            "transportState" : {
                "Label": "Deleted"
             },
             "locked" : false
        },
        "transportstate": {
            "Label": "Deleted"
        }           
    }
]

我考虑过这样做:

var transportlist = await _context.Set<Transport>()
       .Include(transport => transport.TransportState)
       .Select(transport =>
           new
           {
               _mapper.Map<TransportDto>(transport),
           }
        )
        .Take(limitNumber)
        .ToListAsync();

 return transportlist;

但是,如果我这样做,则JSON中的属性transportstate等于NULL。

因此,我尝试进行嵌套映射,在该映射中应同时映射Transport及其对象属性。请注意,所有属性都具有完全相同的名称。

我写了一个Profile进行映射,它是:

public class TransportsProfile : Profile
    {
        public TransportsProfile()
        {
            CreateMap<TransportState, TransportStateForTransportDto>();
            CreateMap<Transport, TransportDto>();
        }
    }

谢谢您的帮助。

entity-framework .net-core automapper dto
1个回答
0
投票
var transportlist = await _context.Set<Transport>() .ProjectTo<TransportDto>(_mapper.Configuration) .Take(limitNumber) .ToListAsync();

鉴于您的TransportDTO包含对相关TransportState DTO的引用,自动映射器应能够准确告诉EF相关实体需要哪些字段以确保正确加载它们。 Map的问题在于,它实际上是针对加载的对象的,而不是EF否则可能会转换为SQL的表达式。

使用Take时,您还应该具有Order By子句,以确保当存在超过该限制的情况下,返回的项目是可预测的。

[就像使用Select进行投影一样,无需急于加载任何相关详细信息或禁用延迟加载。如果您的DTO纯粹是简单的数据容器,并且其中不包含对实体的引用,那么EF只会简单地构成一个查询来提取必填字段。

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