AutoMapper中的 .ForMember 用于集合类型

8
我有一个实体Request和模型RequestModel
public class RequestModel : BaseModel
{
    public IEnumerable <int> Recipients { get; set; }
}

public class Request : IIdent
{
    public virtual ICollection <RequestComment> Comments { get; set; }
}

public class RequestComment : IIdent
{
   [ForeignKey("User")]
   public int? UserId { get; set; }
}

我希望为“收件人”创建映射。
CreateMap<Request, RequestModel>()
      .ForMember(d => d.Recipients, o => o.MapFrom(s => s.Comments.Select(x => x.UserId )))

但我得到了异常:

捕获了AutoMapper.AutoMapperMappingException _HResult=-2146233088 HResult=-2146233088 IsTransient=false Message=映射类型: 请求 -> IEnumerable1 AttManager.Data.Request -> System.Collections.Generic.IEnumerable1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] 目标路径: RequestModel.Recipients.Recipients 源值: AttManager.Data.Request

1个回答

6
问题出现在尝试将 IEnumerable<RequestComment> 转换为 IEnumerable<int> 时,因此 Automapper 将尝试找到 RequestCommentint 的转换,但是未定义。

您可以像这样定义从 RequestCommentint 的转换:

.CreateMap<RequestComment, int>().ConvertUsing(rm => rm.UserId ?? 0);

请求模型之间的映射关系:

.CreateMap<Request, RequestModel>()
.ForMember(d => d.Recipients, o => o.MapFrom(s => s.Comments))

此外,解决您的问题的另一种方法是定义一个AfterMap操作:
.CreateMap<Request, RequestModel>()
.AfterMap((r, rm) => rm.Recipients = new List<int>(r.Comments.Select(c => c.UserId ?? 0)));

我只是添加了 ? 0,因为 UserId 类型是 int?,所以需要将其转换为 int 以适用于 Recipients 属性。


谢谢!第一种方式运行良好,但是第二种方式我遇到了一些问题... 在映射中也会出现异常。我是否应该在使用.AfterMap()之前添加像.ForMember(d => d.Recipients, o => o.PreserveAndIgnore())这样的代码? - demo
@demo:我刚刚测试了单个映射的内存,但如果您正在使用可查询的投影,则“AfterMap”不是一个选项,对此我很抱歉。 - Arturo Menchaca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接