问题描述:

I have linked list kind of situation. My DTO looks like this -

public class DTOItem

{

public string ID

{

get;

set;

}

public int? UniqueId

{

get;

set;

}

public string Payload

{

get;

set;

}

//How do I map this guy? It is list of same type.

public List<DTOItem> RelatedItems

{

get;

set;

}

}

How do I map this guy using AutoMapper? I am able to map other members of the class. Data is mapped from another class' collection object that has a different set of member not identical to this class.

public List<DTOItem> RelatedItems

{

get;

set;

}

Thanks in advance.

UPDATE: Here is the code -

Raphael, here is the code:

The Source Objects:

public class ResultsSet

{

public int? ResultId

{

get;

set;

}

public int UID

{

get;

set;

}

//Returns large XML string

public string ResultBlob

{

get;

set;

}

public RelatedItems[] RelatedSet

{

get;

set;

}

}

public class RelatedItems

{

public int Item_ID

{

get;

set;

}

public int Relationship_ID

{

get;

set;

}

public string Description

{

get;

set;

}

}

To map here is the code:

Mapper.CreateMap<ResultSet, DTOItem>()

.ForMember(dest => dest.ID, opt => opt.MapFrom(src => src.ResultID.GetValueOrDefault(0)))

.ForMember(dest => dest.UniqueId, opt => opt.MapFrom(src => src.UID))

.ForMember(dest => dest.Payload, opt => opt.MapFrom(src => src.ResultBlob));

/*

How do I map RelatedSet to RelatedItems here?

*/

Mapper.Map(result, returnResult);

Thanks again.

网友答案:

No need to use AutoMapper for this. For non-cyclic, relatively flat data, this should do:

static Func<RelatedItems, DTOItem> MapRelated(IEnumerable<ResultsSet> all) {
    var map = MapResultSet(all);
    return relatedItem => map(all.First(x => x.UID == relatedItem.Item_ID));
}

static Func<ResultsSet, DTOItem> MapResultSet(IEnumerable<ResultsSet> all) {
    return s => 
        new DTOItem {
            ID = s.ResultId.GetOrElse(0).ToString(),
            UniqueId = s.UID,
            Payload = s.ResultBlob,
            RelatedItems = (s.RelatedSet ?? new RelatedItems[0]).Select(MapRelated(all)).ToList()
        };
}

Sample usage:

var data = new[] { 
    new ResultsSet {
        UID = 1,
        RelatedSet = new[] {
            new RelatedItems { Item_ID = 2 },
            new RelatedItems { Item_ID = 3 },
        },
    },
    new ResultsSet {
        UID = 2,
    },
    new ResultsSet {
        UID = 3,
    },
};
var items = data.Select(MapResultSet(data)).ToList();
Debug.Assert(items.Count == 3);
Debug.Assert(items[0].UniqueId == 1);
Debug.Assert(items[1].UniqueId == 2);
Debug.Assert(items[2].UniqueId == 3);
Debug.Assert(items[0].RelatedItems.Count == 2);
Debug.Assert(items[0].RelatedItems[0].UniqueId == items[1].UniqueId);
Debug.Assert(items[0].RelatedItems[1].UniqueId == items[2].UniqueId);

I assumed Item_ID is the 'key' to UID, otherwise simply adjust MapRelated.

Generally speaking, I think AutoMapper is only useful if you have to map untyped data into typed data, and even in that case I'd think really hard before using it. Otherwise, some LINQ code is simpler and more type safe.

相关阅读:
Top