具有相同类型的嵌套Dtos的Dto失败

时间:2015-10-15 09:24:51

标签: c# asp.net-mvc automapper automapper-4

我在一个项目中遇到了问题,并在一个裸测试项目中成功地重新编写了它。

我有以下dtos:

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(显然)。

AutoMapper配置:

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.

当然,这是来自automapper的问题。

现在我尝试了以下内容:

 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的直接映射导致空值(或Id为​​0)。因此,context.Users.ProjectTo<AppUserDto>().FirstOrDefault()(或甚至Mapper.Map<AppUserDto>(context.Users.FirstOrDefault()))始终返回AppUserDto,其中包含道具的默认值。

那么,如何在不牺牲直接映射到所述dto对象的情况下,在同一个基本dto中创建多个相同类型的嵌套dto对象?

使用ProjectUsing解决问题(如果我们可以让直接映射同时工作)不太理想,但如果这是唯一可行的方法,我可以管理。

修改

对于任何有兴趣的人,最有可能发生错误this is the github issue

1 个答案:

答案 0 :(得分:3)

罪魁祸首实际上是MaxDepth召唤本身。看起来似乎并非如此,但在我看到的每个映射上粘贴MaxDepth可能会产生副作用。

事实证明,我根本没有对我的Dtos进行递归(这就是MaxDepth的用途)。因此,只需删除所有MaxDepth次调用即可解决此问题,而无需ProjectUsing

这已被清除here