这是我对实体框架的查询:
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>();
}
}
谢谢您的帮助。
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只会简单地构成一个查询来提取必填字段。