首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AutoMapper:在传递属性时将单个对象映射到IEnumerable/子对象集合

AutoMapper:在传递属性时将单个对象映射到IEnumerable/子对象集合
EN

Stack Overflow用户
提问于 2019-09-07 16:38:34
回答 2查看 943关注 0票数 0

我有以下两个ShopifySharp对象。

代码语言:javascript
复制
public class Product
{            
    public string Title { get; set; }

    public string BodyHtml { get; set; }

    public IEnumerable<ProductVariant> Variants { get; set; }
}


public class ProductVariant 
{
    public string Title { get; set; }

    public string Barcode { get; set; }

}

然后我有了下面的模型

代码语言:javascript
复制
public class ShopifyVariant 
{
    public long Id { get; set; }

    public long ProductId { get; set; }

    public string ProductName { get; set; }

    public string VariantName { get; set; }

    public string Price { get; set; }
}

我希望将ShopifySharp.Product的一个实例映射到IEnumerable<ShopifyVariant>,因为每个ShopifySharp.Product总是至少有一个ProductVariant

通常,这是一个微不足道的问题,因为您可以简单地创建两个对象之间的映射,如下所示:

代码语言:javascript
复制
this.CreateMap<ShopifySharp.ProductVariant, ShopifyVariant>()

但是我需要获取每个变体的ProductName和ProductId,它们只能从ShopifySharp.Product对象中获得。

我最初的想法是尝试像这样的东西

代码语言:javascript
复制
this.CreateMap<ShopifySharp.ProductVariant, ShopifyVariant>()
.ForMember(o => o.Id, o => o.MapFrom(f => f.Id))
.ForMember(o => o.ProductId, o => o.MapFrom((src, dest, m, c) => c.Items["ProductId"]))
.ForMember(o => o.ProductName, o => o.MapFrom((src, dest, m, c) => c.Items["ProductName"]))
.ForMember(o => o.VariantName, o => o.MapFrom(f => f.Title));

this.CreateMap<ShopifySharp.Product, IEnumerable<ShopifyVariant>>()

但我不清楚如何实际创建从产品到IEnumerable的投影。

我目前正在尝试使用自定义ITypeConverter,但还没有解决这个问题。

有人能帮上忙吗?如何将对象的单个实例映射到精简实体的集合?

EN

回答 2

Stack Overflow用户

发布于 2019-09-07 19:26:28

我已经使用以下映射解决了这个问题(不是最优的)。

代码语言:javascript
复制
this.CreateMap<ShopifySharp.ProductVariant, ShopifyVariant>().ForMember(o => o.Id, o => o.MapFrom(f => f.Id))
.ForMember(o => o.ProductId, o => o.MapFrom(f => f.ProductId))
.ForMember(o => o.VariantName, o => o.MapFrom(f => f.Title))
.ForMember(o => o.Barcode, o => o.MapFrom(f => f.Barcode))
.ForMember(o => o.Price, o => o.MapFrom(f => f.Price))
.ForMember(o => o.Grams, o => o.MapFrom(f => f.Grams))
.ForMember(o => o.Taxable, o => o.MapFrom(f => f.Taxable))
.ForMember(o => o.Weight, o => o.MapFrom(f => f.Weight))
.ForMember(o => o.WeightUnit, o => o.MapFrom(f => f.WeightUnit))
.ForMember(o => o.SKU, o => o.MapFrom(f => f.SKU));

this.CreateMap<ShopifySharp.Product, ShopifyVariant>().ForMember(o => o.ProductName, o => o.MapFrom(f => f.Title));

this.CreateMap<IEnumerable<ShopifySharp.Product>, IEnumerable<ShopifyVariant>>()
.ConvertUsing<ShopifyProductsToVariantsCollectionTypeConverter>();

internal class ShopifyProductsToVariantsCollectionTypeConverter : ITypeConverter<IEnumerable<ShopifySharp.Product>, IEnumerable<ShopifyVariant>>
{
    public IEnumerable<ShopifyVariant> Convert(IEnumerable<ShopifySharp.Product> source, IEnumerable<ShopifyVariant> destination, ResolutionContext context)
    {
        var result = new List<ShopifyVariant>();
        foreach (var product in source)
        {
            foreach (var variant in product.Variants)
            {
                var mappedVariant = context.Mapper.Map<ShopifyVariant>(variant);
                context.Mapper.Map(product, mappedVariant);
                result.Add(mappedVariant);
            }
        }

        return result;
    }
}

会很乐意看到更好的方法。

票数 0
EN

Stack Overflow用户

发布于 2019-09-07 20:56:10

正如我在评论中所说的,一些LINQ在这里会有很大的帮助。但事实就是这样。您可以将相同的想法应用于您的版本。你拥有的大多数MapFrom都是无用的。

代码语言:javascript
复制
c.CreateMap<ProductVariant, ShopifyVariant>()
    .ForMember(o => o.ProductId, o => o.MapFrom((src, dest, m, context) => context.Items["ProductId"]))
    .ForMember(o => o.ProductName, o => o.MapFrom((src, dest, m, context) => context.Items["ProductName"]))
    .ForMember(o => o.VariantName, o => o.MapFrom(f => f.Title));
c.CreateMap<Product, IEnumerable<ShopifyVariant>>().ConvertUsing((product,variant,context)=>
{
    context.Items["ProductId"] = product.Id;
    context.Items["ProductName"] = product.Name;
    return context.Mapper.Map<List<ShopifyVariant>>(product.Variants);
});

new []{new Product{Id=1,Variants=new[]{new ProductVariant{Id=1},new ProductVariant{Id=2}}}, new Product{Id=2,Variants=new[]{new ProductVariant{Id=3},new ProductVariant{Id=4}}}}
.SelectMany(product=>mapper.Map<List<ShopifyVariant>>(product,_=>{}));

在调用Map时,可以省略IEnumerable映射,并用相同的代码内联替换。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57832069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档