自动映射和复杂对象

时间:2017-12-07 23:12:18

标签: c# automapper

我有一个复杂的对象,我需要在简单的DTO对象列表上进行翻译。

我的地图是这样的:

CreateMap<ObjASource, IEnumerable<MyDto>>()
            .ConvertUsing(source => source.ObjB?.ObjC?.Select(p => new MyDto
            {
                field1 = source.field1,
                field2 = source.field2,
                field3 = source.field3,
                field4 = p.fieldX,
                field5 = p.fieldY
            }).ToList()
            );

当我使用singol ObjA时,这张地图效果很好  喜欢这个mapper.Map<IList<MyDto>>(my_singol_objA);,但在我使用ObjA mapper.Map<IList<MyDto>>(my_list_of_objA);

列表时不起作用

我不知道我需要添加哪种其他类型的地图来纠正这个问题。

谢谢你们

已编辑,因为我没有解决

我想以更简单的方式解释我的问题,也许有人可以帮助我。 我在Collection中有一个复杂的对象。

像这样的对象:

public class Product { 
    int product_id {get; set;}; 
    string name {get; set;}; 
    List<CompaniesProvideProduct> company  {get; } 
}

CompaniesProvideProduct包含与销售该产品的公司的关系,并提供更多详细信息。

public class CompaniesProvideProduct { 
    int product_id {get; set;}; 
    int company_id {get; set;}; 
    decimal price {get; set;}; 

}

然后我翻译的目标对象是:

public class ProductDto { 
    int product_id {get; set;}; 
    string name {get; set;}; 
    int company_id {get; set;}; 
    decimal price {get; set;}; 

}

在我的程序中,我从db得到一个List,我想在List中翻译这个对象。对于1个产品记录,我将有更多的ProductDto记录。

我尝试过:

CreateMap<Product, ProductDto>(); //to get product_id and name
CreateMap<CompaniesProvideProduct, ProductDto>(); //to get company_id and price

CreateMap<Product, IEnumerable<ProductDto>>()
.ConvertUsing<ProductConverter>();

public class ProductConverter : ITypeConverter<Product, IEnumerable<ProductDto>>
{

    IEnumerable<ProductDto> ITypeConverter<Product, IEnumerable<ProductDto>>.Convert(Product source, IEnumerable<ProductDto> destination, ResolutionContext context)
    {
        Product prod = source;
        foreach (var dto in prod.company.Select(e => context.Mapper.Map<ProductDto>(e)))
        {
            context.Mapper.Map(prod, dto);
            yield return dto;
        }
    }
}

但这对我不起作用。如果有人可以帮助我,我会很开心。

感谢。

1 个答案:

答案 0 :(得分:0)

@Lucian是对的。默认情况下处理集合。因此,如果原始映射设置正确object => list<object>,那么list<object> => list<list<object>>也可以正常工作。

           expression.CreateMap<ObjASource, List<MyDto>>()
                .ConvertUsing(source =>
                    {
                        return source.ObjB?.ObjC?.Select(p => new MyDto
                        {
                            field1 = source.field1,
                            field2 = source.field2,
                            field3 = source.field3,
                            field4 = p.fieldX,
                            field5 = p.fieldY
                        })
                        .ToList();
                    }
            );

这是工作样本:

        var test = new List<ObjASource>
        {
            new ObjASource
            {
                field1 = "1",
                field2 = "2",
                field3 = "3",
                ObjB = new ObjB
                {
                    ObjC = new List<ObjC>
                    {
                        new ObjC
                        {
                            fieldX = "X",
                            fieldY = "Y"
                        }
                    }
                }
            }
        };

        var result = Mapper.Map<List<List<MyDto>>>(test);

<强>更新

因此,根据您更新的问题,我认为我更了解您的问题。基本上你需要2个显式映射 - object => List<object>List<object> => List<object> - 因为如前所述,AutoMapper给出了你不想要的对象List列表:

        var mapper = new MapperConfiguration(exp =>
        {
            exp.CreateMap<List<Product>, List<ProductDto>>()
                .ConstructUsing(products => products.SelectMany(product => product.company,
                    (product, companiesProvideProduct) => new ProductDto
                    {
                        product_id = product.product_id,
                        name = product.name,
                        company_id = companiesProvideProduct.company_id,
                        price = companiesProvideProduct.price
                    }).ToList());

            exp.CreateMap<Product, List<ProductDto>>()
                .ConvertUsing(product => product.company.Select(provideProduct => new ProductDto
                {
                    product_id = product.product_id,
                    name = product.name,
                    company_id = provideProduct.company_id,
                    price = provideProduct.price
                }).ToList());
        }).CreateMapper();

那么如果您的对象初始化如下所示:

        var productList = new List<Product>
        {
            new Product
            {
                product_id = 1,
                name = "test1",
                company = new List<CompaniesProvideProduct>
                {
                    new CompaniesProvideProduct
                    {
                        company_id = 1,
                        price = 1.99m,
                        product_id = 1
                    }
                }
            },
            new Product
            {
                product_id = 2,
                name = "test2",
                company = new List<CompaniesProvideProduct>
                {
                    new CompaniesProvideProduct
                    {
                        company_id = 2,
                        price = 1.99m,
                        product_id = 2
                    }
                }
            }
        };

映射的对象是:

var result1 = mapper.Map<List<ProductDto>>(productList);
var result2 = mapper.Map<List<ProductDto>>(productList.First());