I have an entity that is actually tree object structure (defining only relevant properties within my entity):
我有一个实体,实际上是树对象结构(仅定义我的实体中的相关属性):
public class TreeItem
{
public int Id { get; set; }
public TreeItem Parent { get; set; }
public List<TreeItem> Children { get; set; }
...
}
Parent and Children properties are correctly defined as navigational properties. So when I call something like:
父和子属性被正确定义为导航属性。所以,当我打电话给:
var items = (from ti in context.TreeItem()
select ti).ToList<TreeItem>();
I actually get my items in a tree structure, because EF works its magic behind the curtain and populates my Parents and Children on these items.
我实际上把我的物品放在一个树形结构中,因为EF在幕后工作,并在我的父母和孩子身上填充这些物品。
What I would like to do now is to convert these objects into my ViewModel objects that are very much POCO. No functionality, just data.
我现在想要做的是将这些对象转换为非常多POCO的ViewModel对象。没有功能,只有数据。
I could convert these by having a recursive method that would create and populate new objects, but is there a simpler (in terms of LoC - lines of code) way to do this kind of conversion?
我可以通过一个可以创建和填充新对象的递归方法来转换它们,但是有更简单的(就LoC而言 - 代码行)方式来进行这种转换吗?
1 个解决方案
#1
1
In this related question several approaches are discussed:
在这个相关问题中,讨论了几种方法:
- The recursive one, will probably be the easiest to implement, however in terms of scaling for depth and number of items, it is limited as it tends to exponentially take longer and risks overflowing your stack
- 递归的,可能是最容易实现的,但是在深度和项目数量的缩放方面,它是有限的,因为它倾向于指数地花费更长的时间并且冒着溢出堆栈的风险
- Another approach would be to use a stack which in terms of scaling has a much more linear growth
- 另一种方法是使用在缩放方面具有更多线性增长的堆栈
Be sure to check out Eric Lippert's comment at the bottom of the page.
请务必查看页面底部的Eric Lippert的评论。
Update, to give you an idea of what I mean:
更新,让您了解我的意思:
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;
}
}
Call it like so:
这样称呼它:
treeItems.TransformTree<TreeItem, TreeItemPoco>(
(item) => { return item.Children; },
(pocoItem) => { return pocoItem.Children; },
(item) => { return new TreeItemPoco(item); });
#1
1
In this related question several approaches are discussed:
在这个相关问题中,讨论了几种方法:
- The recursive one, will probably be the easiest to implement, however in terms of scaling for depth and number of items, it is limited as it tends to exponentially take longer and risks overflowing your stack
- 递归的,可能是最容易实现的,但是在深度和项目数量的缩放方面,它是有限的,因为它倾向于指数地花费更长的时间并且冒着溢出堆栈的风险
- Another approach would be to use a stack which in terms of scaling has a much more linear growth
- 另一种方法是使用在缩放方面具有更多线性增长的堆栈
Be sure to check out Eric Lippert's comment at the bottom of the page.
请务必查看页面底部的Eric Lippert的评论。
Update, to give you an idea of what I mean:
更新,让您了解我的意思:
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;
}
}
Call it like so:
这样称呼它:
treeItems.TransformTree<TreeItem, TreeItemPoco>(
(item) => { return item.Children; },
(pocoItem) => { return pocoItem.Children; },
(item) => { return new TreeItemPoco(item); });