我在一个项目中遇到了一个问题,并在一个裸测试项目中成功地重现了它。
我有以下 dto:
public class AppUserDto
{
public int Id { get; set; }
public string Name { get; set; }
}
public class IssueDto
{
public int Id { get; set; }
public AppUserDto Owner { get; set; }
public AppUserDto Creator { get; set; }
}
对应的模型是完全一样的,只是有模型关系而不是 DTO(很明显)。
自动映射器配置:
Mapper.CreateMap<AppUser, AppUserDto>().MaxDepth(1);
Mapper.CreateMap<Issue, IssueDto>().MaxDepth(1);
最简单的查询:
var i = context.Issues.ProjectTo<IssueDto>().FirstOrDefault();
这总是抛出一个NotSupportedException
:
The type 'AppUserDto' appears in two structurally incompatible initializations within a single LINQ to Entities query. A type can be initialized in two places in the same query, but only if the same properties are set in both places and those properties are set in the same order.
这当然是自动映射器的问题。
现在我尝试了以下方法:
Mapper.CreateMap<AppUser, AppUserDto>().MaxDepth(1)
.ProjectUsing(u => new AppUserDto
{
Id = u == null ? -1 : u.Id,
Name = u == null ? null : u.Name,
});
这使得查询context.Issues.ProjectTo<IssueDto>()...
成功。但这反过来会直接映射AppUser
结果为空值(或 0 表示 Id)。所以context.Users.ProjectTo<AppUserDto>().FirstOrDefault()
(甚至Mapper.Map<AppUserDto>(context.Users.FirstOrDefault())
)总是返回一个AppUserDto
带有默认值的 props。
那么,如何在不牺牲对所述 dto 对象的直接映射的情况下使同一基本 dto 中的多个嵌套 dto 对象在同一个基础 dto 中工作?
使用 ProjectUsing 解决问题(如果我们可以同时进行直接映射)并不理想,但如果这是我能做到的唯一方法。
编辑:
很可能有一个错误,这是任何感兴趣的人的 github 问题。