我有以下两个ShopifySharp
对象。
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; }
}
然后我有以下模型
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
。
通常这将是一个小问题,因为您可以按照以下方式简单地在两个对象之间创建一个映射:
this.CreateMap<ShopifySharp.ProductVariant, ShopifyVariant>()
但是我需要获取每个变体的ProductName和ProductId,这些变体只能从ShopifySharp.Product
对象获得。
我最初的想法是尝试这样的事情
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>>()
但是我不清楚如何实际创建从Product到IEnumerable的投影。
我目前正在使用自定义ITypeConverter
,但尚未解决。
有人可以帮忙吗?您如何将一个对象的单个实例映射到精简实体的集合?
答案 0 :(得分:0)
我已经使用以下映射(次优)解决了这个问题。
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;
}
}
希望看到更好的方法。
答案 1 :(得分:0)
正如我在评论中已经说过的那样,一些LINQ在这里会有所帮助。但是在这里。您可以将相同的想法应用于您的版本。您拥有的大多数MapFrom
都没用。
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,_=>{}));
调用IEnumerable
时,Map
映射可以省略,并用相同的代码内联替换。