首页 > 解决方案 > 使用 AutoMapper 协助迭代对象

问题描述

我遇到了一些地图问题,希望社区可以提供帮助。我正在使用AutoMapper6.0 版在对象之间建立连接。我有三个具有以下结构的对象(一般命名,因为数据本身并不重要):

public ObjectA {
    string field1 { get; set; }
    string field2 { get; set; }
    string field3 { get; set; }
    string field4 { get; set; }
}

public ObjectB {
    string field1 { get; set; }
    string field2 { get; set; }
    List<ObjectC> ObjectC { get; set; }
}

public ObjectC {
    string field3 { get; set; }
    string field4 { get; set; }
}

我有几个这样的地图设置:

Mapper.Initialize(cfg => {
    cfg.CreateMap<ObjectC, ObjectA>();
    cfg.CreateMap<ObjectB, ObjectA>();
});

这让我想到了我的问题。ObjectA是数据库表及其字段的直接表示,我想使用ObjectB来创建对表中条目的检查ObjectA,并添加任何尚不存在的条目。我的问题是我似乎不明白如何在我检查每个可能的变体之间建立正确的连接ObjectBObjectA通过它来创建.AutoMapperObjectBObjectA

最终目标应该是这样的:

ObjectA objectA = // mapped data from ObjectB with the contents of List Item [0]
var objectAExists = _dataHandlers.GetObjectA;
if (objectAExists)
{
   // some code to return use to iterate back that this variant is in the DB already
   log.Info("ObjectA Already Exists");
}
else
{
    var results = storeContents(objectA);
    log.Info("New Contents Stored");
}
// return to top of iteration and this time process with contents using ObjectB.ObjectC[1] being used, and so on.

我尝试了一系列方法,例如:

// try to iterate through each List item...
for (int i = 0; i < ObjectB.ObjectC.Count; i++) {  
    //I wanted this to map the contents like so:
    ObjectA objectA = new ObjectA() {
        Field1 = ObjectB.Field1,
        Field2 = ObjectB.Field2,
        Field3 = ObjectB.ObjectC[i].Field3,
        Field4 = ObjectB.ObjectC[i].Field4
    }
    // but I couldn't figure out how to make a similar association using AutoMapper...
}

// tried to iterate through each with a foreach loop... but was in a similar situation as above... 
foreach (var objectC in ObjectB.ObjectC)  { // some code... }

// I tried double mapping...
    var objectA = Mapper.Map<ObjectA>(ObjectB);
    objectA = Mapper.Map<ObjectA>(objectC); // new problem hits here
// when I attempted to add the data from the new mapping, it overwrote the data populated by the first mapping...
// Change '=' to '+=' wasn't possible, so that didn't help...

// altering the mapper...
   cfg.CreateMap<ObjectB, ObjectA>()
       .Include<ObjectC, ObjectA>();

甚至尝试使用类型转换器......但遇到了另一面墙。不用说,我的想法很少,AutoMapper 文档似乎没有提供足够的信息来帮助解决这个问题。任何可以为我指出解决方案的建议将不胜感激......

谢谢大家。

标签: c#automapper

解决方案


也许您正在寻找的是一个映射表达式,它指定只有在尚未设置目标属性时才应该映射它。这样映射是有条件的。如果目标属性尚未设置,它将从源映射。如果目标已被填充,则不会被覆盖。

Mapper.Initialize(
    cfg =>
    {
        cfg.CreateMap<ObjectB, ObjectA>()
            .ForMember(src => src.field2,
                opt => opt.ResolveUsing((src, dest) => 
                    dest.field2 = dest.field2 ?? src.field2
                ));
    }); 

推荐阅读