【问题标题】:Automapper and complex object自动映射器和复杂对象
【发布时间】:2017-12-07 23:12:17
【问题描述】:

我有一个复杂的对象,我需要在一个简单 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&lt;IList&lt;MyDto&gt;&gt;(my_singol_objA); 但在我处理 ObjA 列表时不起作用mapper.Map&lt;IList&lt;MyDto&gt;&gt;(my_list_of_objA);

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

谢谢大家

已编辑,因为我没有解决

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

这样的对象:

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

CompanyProvideProduct 包含与销售该产品的公司的关系并具有更多详细信息。

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 得到一个列表,我想在列表中翻译这个对象。对于 1 条 Product 记录,我将拥有更多 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;
        }
    }
}

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

谢谢。

【问题讨论】:

  • 集合是默认处理的,不需要为它们映射。
  • 谢谢@LucianBargaoanu 我知道这一点,但我的映射不正确,我收到错误。

标签: c# automapper


【解决方案1】:

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

           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 =&gt; List&lt;object&gt;List&lt;object&gt; =&gt; List&lt;object&gt; - 因为如前所述 AutoMapper 给出了你不想要的对象列表列表:

        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());

【讨论】:

  • 谢谢 ODawg,如果我像你写的那样翻译,我的映射就可以工作。但问题是我不想要另一个集合的集合。我只想要一个收藏。我的 ObjB 继承自 ObjA,他有更多细节,ObjC 是 ObjB 和另一个类的关系,为此我有一个 ObjC 的集合。我希望我的翻译给我一个 ObjB 对象的集合,其中包含我在 ObjC 中的关系细节。我不知道我的解释是否清楚。
猜你喜欢
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多