题
我有一个实体实际上是树的对象结构(限定只有相关属性,在我的实体):
public class TreeItem
{
public int Id { get; set; }
public TreeItem Parent { get; set; }
public List<TreeItem> Children { get; set; }
...
}
父母和儿童的性能被正确地定义为导航性能。所以当我打电话是这样的:
var items = (from ti in context.TreeItem()
select ti).ToList<TreeItem>();
我实际上得到我的项目在一棵树的结构,因为EF工作的魔法背后的窗帘和填充我父母和儿童在这些项目。
我想现在要做的就是要转换这些物体进入我的视图模型的对象是非常POCO。没有的功能,只需的数据。
我可以把这些具有通过递归的方法,将建立和填充新的对象,但是有一个简单的(在条款的LoC线的代码)的方式做这样的转换?
解决方案
在 此 相关问题的几种方法是讨论:
- 递一个,可能是最容易实现,然而在条款的扩展深度和数目的项目,它是有限的,因为它往往成倍增长需要更长的时间和风险溢出你的筹码
- 另一个办法是使用一堆这在方面的扩展有一个更直线增长
一定要检查了埃里克利珀特的评论底部的网页。
更新,让你知道我的意思是:
public static class Extensions
{
public static IList<R> TransformTree<T, R>(this IEnumerable<T> collection,
Func<T, IEnumerable<T>> entitySelector,
Func<R, IList<R>> pocoSelector,
Func<T, R> transformer)
{
var transformedList = new List<R>();
var stack = new Stack<IEnumerable<T>>();
var parents = new Dictionary<IEnumerable<T>, R>();
stack.Push(collection);
while (stack.Count > 0)
{
IEnumerable<T> items = stack.Pop();
R transformedParent;
IList<R> parentChildren = parents.TryGetValue(items, out transformedParent)
? pocoSelector(transformedParent)
: transformedList;
foreach (var item in items)
{
R transformedItem = transformer(item);
parentChildren.Add(transformedItem);
IEnumerable<T> children = entitySelector(item);
stack.Push(children);
parents.Add(children, transformedItem);
}
}
return transformedList;
}
}
叫它,像这样:
treeItems.TransformTree<TreeItem, TreeItemPoco>(
(item) => { return item.Children; },
(pocoItem) => { return pocoItem.Children; },
(item) => { return new TreeItemPoco(item); });
不隶属于 StackOverflow