我有一个自我引用模型,我想将其转换为平面列表。模型看起来像这样。
public class Node
{
public List<Node> Nodes { get; set; }
public Person Person { get; set; }
public Language Language { get; set; }
}
public class NodeDTO
{
public PersonDTO Person { get; set; }
public LanguageDTO Language { get; set; }
}
public class NodeListDTO
{
public List<NodeDTO> Nodes { get; set; }
}
我希望层次结构中的所有节点都平放到我的DTO对象中的一个列表中。这可以使用Auto Mapper。
我曾尝试使用自定义值解析器,但我还没有想出如何在值解析器中使用PersonDTO和LanguageDTO的映射。
答案 0 :(得分:2)
首先,您需要代码来压缩节点层次结构。 AutoMapper不会自动执行此操作。我使用以下扩展方法:
public static IEnumerable<T> Flatten<T>(this T root,
Func<T, IEnumerable<T>> childrenSelector)
{
if (!typeof(T).IsValueType && root == null)
throw new ArgumentNullException(nameof(root));
return Flatten(new[] { root }, childrenSelector);
}
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source,
Func<T, IEnumerable<T>> childrenSelector)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (childrenSelector == null)
throw new ArgumentNullException(nameof(childrenSelector));
return FlattenIterator(source, childrenSelector);
}
private static IEnumerable<T> FlattenIterator<T>(this IEnumerable<T> source,
Func<T, IEnumerable<T>> childrenSelector)
{
if (source != null)
{
foreach (var item in source)
{
yield return item;
var children = childrenSelector(item);
if (children != null)
foreach (var child in FlattenIterator(children, childrenSelector))
yield return child;
}
}
}
接下来 - 您需要告诉AutoMapper如何拼合并将节点层次结构映射到列表
MapperConfiguration config = new MapperConfiguration(c =>
{
c.CreateMap<Person, PersonDTO>();
c.CreateMap<Language, LanguageDTO>();
c.CreateMap<Node, NodeDTO>();
c.CreateMap<Node, NodeListDTO>()
.ForMember(d => d.Nodes, o => o.ResolveUsing(s => s.Flatten(n => n.Nodes)));
});
现在你可以简单地使用
了var node = new Node {
Person = new Person { Id = 1, Name = "Bob" },
Language = new Language { Id = 10, Code = "en" },
Nodes = new List<Node> {
new Node {
Person = new Person { Id = 3, Name = "Mike"},
Language = new Language { Id = 11, Code = "es"},
Nodes = new List<Node> {
new Node {
Person = new Person { Id = 4, Name = "Alex"},
Language = new Language { Id = 11, Code = "es"}
}
}
},
new Node {
Person = new Person { Id = 5, Name = "Serge"},
Language = new Language { Id = 12, Code = "by"}
}
}
};
var nodeListDTO = mapper.Map<NodeListDTO>(node);
结果:
{
"Nodes": [
{
"Person": { "Id": 1, "Name": "Bob" },
"Language": { "Id": 10, "Code": "en" }
},
{
"Person": { "Id": 3, "Name": "Mike" },
"Language": { "Id": 11, "Code": "es" }
},
{
"Person": { "Id": 4, "Name": "Alex" },
"Language": { "Id": 11, "Code": "es" }
},
{
"Person": { "Id": 5, "Name": "Serge" },
"Language": { "Id": 12, "Code": "by" }
}
]
}