如何使用AutoMapper将IEnumerable映射到List

Coo*_*Tek 5 c# automapper

我试图将IEnumerable映射到List.我不知道如何让它发挥作用.这是我到目前为止所尝试的.

我收到错误"只有类型的顶级个人成员才支持成员的自定义配置."

Source: IEnumerable<Source>
Target: List<Target>

AutoMapper.Mapper.Map(sourceIEnum, TargetList);

Mapper.CreateMap<IEnumerable<Source>, List<Target>>()
    .ForMember(f => f, mp => mp.MapFrom(
                                    mfrom => mfrom.Select(s => AutoMapper.Mapper.Map(s, new Target())
                                ).ToList())
              );

Mapper.CreateMap<Source, Target>()
    .ForMember(f => f.TargetPropertyA, mp => mp.MapFrom(mfrom => mfrom.FromA.Value))
    .ForMember(f => f.TargetPropertyB, mp => mp.MapFrom(mfrom => mfrom.FromB.Value))
    .ForMember(f => f.TargetPropertyC, mp => mp.MapFrom(mfrom => mfrom.FromC.Value))
    .ForMember(f => f.InnerObjectTarget, mp => mp.MapFrom(
                                    mfrom => mfrom.Select(s => AutoMapper.Mapper.Map(s, new InnerObjectTarget())
                                ).ToList())
              );    

Mapper.CreateMap<SourceInner, TargetInner>()
        .ForMember(f => f.TargetInnerPropA, m => m.MapFrom(source => source.InnerA))
        .ForMember(f => f.TargetInnerPropB, m => m.MapFrom(source => source.InnerB))
        .ForMember(f => f.TargetInnerPropC, m => m.MapFrom(source => source.InnerC));
Run Code Online (Sandbox Code Playgroud)

Ger*_*old 5

有几种方法可以映射IEnumerable<Source>IEnumerable<Target>.我将展示三个最方便的.

AdventureWorks数据库(2008R2)为例,我定义了三个DTO类:

class ProductModelDto
{
    public string Name { get; set; }
    public IEnumerable<ProductDto> Products { get; set; }
}

class ProductDto
{
    public string Name { get; set; }
    public string Number { get; set; }
    public IEnumerable<ProductReviewDto> ProductReviews { get; set; }
}

class ProductReviewDto
{
    public string ReviewerName { get; set; }
    public string Email { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是我定义的唯一映射:

Mapper.CreateMap<ProductModel, ProductModelDto>();
Mapper.CreateMap<Product, ProductDto>()
      .ForMember(dto => dto.Number, m => m.MapFrom(p => p.ProductNumber));
Mapper.CreateMap<ProductReview, ProductReviewDto>()
      .ForMember(dto => dto.Email, m => m.MapFrom(pr => pr.EmailAddress));
Run Code Online (Sandbox Code Playgroud)

只是一个查询:

// A ProductModel having a Product with ProductReviews
var query = db.ProductModels.Where(pm => pm.ProductModelID == 64);
Run Code Online (Sandbox Code Playgroud)

现在,在我看来,最方便的方法是将源ProductModels 映射IEnumerable<ProductModelDto>为以下三种:

1. query.Select(Mapper.Map<ProductModelDto>)
2. Mapper.Map<List<ProductModelDto>>(query)
3. query.ProjectTo<ProductModelDto>() (Project().To<> prior to v. 4.1.0)
Run Code Online (Sandbox Code Playgroud)

如果你这样做ToList(),你已经映射IEnumerable到了List.

所有三种选择的输出都相同:

- HL Mountain Pedal
  - HL Mountain Pedal; PD-M562
    - David; david@graphicdesigninstitute.com
    - Jill; jill@margiestravel.com
Run Code Online (Sandbox Code Playgroud)

如您所见,AutoMapper不需要IEnumerables的显式映射定义.不是顶级而不是嵌套集合.当源和目标类中的名称相同时,它还映射嵌套集合,并为集合中的元素定义映射.

案例3是一个特例.它将IQueryable目标投射到目标,这仍然是目标IQueryable.映射应用的谓词仍然转换为SQL,并且查询尝试仅选择数据库中投影所需的字段.当DTO嵌套时,后者并不总是成功,就像在这种情况下一样.Linq-to SQL似乎用选项3执行两个查询(但是3个用于1和2).


Raj*_*dar 2

只要定义了目标的映射,就不需要显式定义IEnumerable<Source>映射List<Target>

如果映射了集合元素类型,Automapper 足够智能,可以自动映射基本集合(List、IEnumerable、Collection 等) 。因此,请删除集合映射之间的所有代码,然后重试。

这个片段..

Mapper.CreateMap<IEnumerable<Source>, List<Target>>()
    .ForMember(f => f, mp => mp.MapFrom(
                                    mfrom => mfrom.Select(s => AutoMapper.Mapper.Map(s, new Target())
                                ).ToList())
              );
Run Code Online (Sandbox Code Playgroud)