具有相同类型的嵌套 Dto 的 Dto 失败
Dto with nested Dtos of the same type fails
我在一个项目中遇到了一个问题,并在裸测试项目中成功重现了它。
我有以下 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(很明显)之外,对应的模型完全相同。
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
的直接映射导致空值(或 0 为 Id)。所以 context.Users.ProjectTo<AppUserDto>().FirstOrDefault()
(甚至 Mapper.Map<AppUserDto>(context.Users.FirstOrDefault())
)总是 return 一个 AppUserDto
其属性具有默认值。
那么,如何在不牺牲所述dto对象的直接映射的情况下使相同类型的多个嵌套dto对象在相同的基础dto中工作?
使用 ProjectUsing 解决问题(如果我们可以同时进行直接映射)不太理想,但如果这是唯一的方法,我可以管理。
编辑:
最有可能存在错误,this is the github issue 对于任何感兴趣的人。
罪魁祸首实际上是 MaxDepth
调用本身。看起来可能并非如此,但如我所见,在每个映射上粘贴 MaxDepth
可能会产生副作用。
事实证明,我的 Dto 根本没有递归(这就是 MaxDepth
的用途)。因此,只需删除所有 MaxDepth
调用即可解决此问题,而无需 ProjectUsing
.
已清除 here。
我在一个项目中遇到了一个问题,并在裸测试项目中成功重现了它。
我有以下 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(很明显)之外,对应的模型完全相同。
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
的直接映射导致空值(或 0 为 Id)。所以 context.Users.ProjectTo<AppUserDto>().FirstOrDefault()
(甚至 Mapper.Map<AppUserDto>(context.Users.FirstOrDefault())
)总是 return 一个 AppUserDto
其属性具有默认值。
那么,如何在不牺牲所述dto对象的直接映射的情况下使相同类型的多个嵌套dto对象在相同的基础dto中工作?
使用 ProjectUsing 解决问题(如果我们可以同时进行直接映射)不太理想,但如果这是唯一的方法,我可以管理。
编辑:
最有可能存在错误,this is the github issue 对于任何感兴趣的人。
罪魁祸首实际上是 MaxDepth
调用本身。看起来可能并非如此,但如我所见,在每个映射上粘贴 MaxDepth
可能会产生副作用。
事实证明,我的 Dto 根本没有递归(这就是 MaxDepth
的用途)。因此,只需删除所有 MaxDepth
调用即可解决此问题,而无需 ProjectUsing
.
已清除 here。