自动映射:忽略尚未设置的集合中的类型

时间:2014-01-23 15:42:28

标签: c# .net automapper

考虑以下情况:

    public class DestinationType1 { }

    public class DestinationType2 { }

    public class SourceType { }

    public class SourceTypeA : SourceType { }

    public class SourceTypeB : SourceType { }

我设置了这些映射:

        Mapper.CreateMap<SourceType, DestinationType2>();

        Mapper.CreateMap<SourceTypeB, DestinationType2>();

        Mapper.CreateMap<SourceType, DestinationType1>();

        Mapper.CreateMap<SourceTypeA, DestinationType1>();

然后尝试映射以下内容:

        var sourceTypes = new List<SourceType>{new SourceTypeA(), new SourceTypeB()};
        var destinationType1s = Mapper.Map<List<DestinationType2>>(sourceTypes);
        var destinationType2s = Mapper.Map<List<DestinationType1>>(sourceTypes);

我想要实现的是,destinationType1s只有一个成员,从源列表中的SourceTypeA映射,而destinationType2s只有一个从SourceTypeB映射。然而,我得到的是从两种源类型映射的两个列表中的两个元素。

这是否可以在某种程度上实现,或者我是否需要编写自己的值解析器或类似的东西?

1 个答案:

答案 0 :(得分:1)

您可以使用OfType LINQ扩展方法来过滤sourceTypes列表。

var sourceTypes = new List<SourceType>{new SourceTypeA(), new SourceTypeB()};
var destinationType1s = Mapper.Map<List<DestinationType1>>(sourceTypes.OfType<SourceTypeA>());
var destinationType2s = Mapper.Map<List<DestinationType2>>(sourceTypes.OfType<SourceTypeB>());

OfType<type>会生成IEnumerable<type>,因此如果您不打算使用它们,也可以删除基础SourceType的2张地图。

如果要筛选多种类型,则可以创建自己的类似于OfType的扩展方法,该方法获取类型列表或获取DestinationType并查找映射到它的类型。以下是使用Mapper.FindTypeMapFor仅过滤兼容类型的内容:

//Mapper.CreateMap<SourceType, DestinationType2>(); -- don't want this!

Mapper.CreateMap<SourceTypeB, DestinationType2>();

//Mapper.CreateMap<SourceType, DestinationType1>(); -- don't want this!

Mapper.CreateMap<SourceTypeA, DestinationType1>();

var sourceTypes = new List<SourceType> { new SourceTypeA(), new SourceTypeB() };
var destinationType1s = Mapper.Map<List<DestinationType1>>(sourceTypes.CompatibleMappedTypes<DestinationType1>());
var destinationType2s = Mapper.Map<List<DestinationType2>>(sourceTypes.CompatibleMappedTypes<DestinationType2>());

...

static class Extensions
{
    public static IEnumerable CompatibleMappedTypes<TDestination>(this IEnumerable source)
    {
        foreach (var s in source)
        {
            if (Mapper.FindTypeMapFor(s.GetType(), typeof(TDestination)) != null) yield return s;
        }
    }
}