1

我有两节课:

public class Element
{
    public Item Item { get; set; }
}

public class Item
{
    public Element Element { get; set; }
}

对于此类,我有具有相同结构的 DTO。此方法为映射创建源数据:

static Element[] CreateElements()
{
    var element2 = new Element();
    return new[]
    {
        new Element(new Item(element2)),
        element2,
        new Element()
    };
}

然后我配置映射和地图元素:

Mapper.CreateMap<Element, ElementDto>();
Mapper.CreateMap<Item, ItemDto>();

var elements = CreateElements();

var mappedElements = elements
    .Select(_ => Mapper.Map(_, typeof(Element), typeof(ElementDto)))
    .OfType<ElementDto>()
    .ToArray();

在我检查映射结果后:

foreach (var element in mappedElements)
{
    Console.WriteLine(mappedElements.Any(e => e?.Item?.Element == element));
}

此代码显示“False”三次。因此,“CreateElements”中的“element2”被创建了两个副本。

对源元素的相同测试将返回“False True False”:

foreach (var element in elements)
{
    Console.WriteLine(elements.Any(e => e?.Item?.Element == element));
}

因为我需要配置映射以免重复元素?可能吗?

4

2 回答 2

1

我不认为这是 AutoMapper 的问题。

您正在创建三个不同的Element项目并将它们映射到某种ElementDto. 它们是三个不同的对象(在结构和引用方面),您不能期望如果将它们映射到相同的类型,它们将是相等的。

如果您考虑您的物品:

    var element2 = new Element();
    return new[]
    {
        new Element(new Item(element2)),
        element2,
        new Element()
    };

并比较它们,您会发现没有一个是相等的。您没有提供ElementDto类,但我的猜测是您应该实现IEquatable接口,这将确保正确比较(或重载运算符)。

于 2015-12-15T07:59:48.667 回答
0

这可以手动完成。首先,忽略ItemAutoMapper 没有复制元素链的属性:

Mapper.CreateMap<Item, ItemDto>()
    .ForMember(_ => _.Element, _ => _.Ignore()); 

其次,手动复制带有标记查看项目的链:

static IEnumerable<ElementDto> MapElements(Element[] elements)
{
    var elementToDtoMap = new Dictionary<Element, ElementDto>();

    foreach (var element in elements)
    {
        MapElement(element, null, elementToDtoMap);
    }

    return elementToDtoMap.Select(_ => _.Value);
}

static void MapElement(Element element, ItemDto parentItem, Dictionary<Element, ElementDto> elementToDtoMap)
{
    ElementDto elementDto = null;
    if (elementToDtoMap.TryGetValue(element, out elementDto))
            return;

    elementDto = Mapper.Map<ElementDto>(element);
    elementToDtoMap.Add(element, elementDto);

    if (parentItem != null)
    {
        parentItem.Element = elementDto;
    }

    if (element.Item != null)
    {
        MapElement(element.Item.Element, elementDto.Item, elementToDtoMap);
    }
}
于 2015-12-18T20:07:32.840 回答