[英]C# linq hierarchical list property set
I have the following class: 我有以下课程:
public class Products
{
public int ID { get; set; }
public int KeyID { get; set; }
public int KeyLevel { get; set; }
public string COMBasis { get; set; }
}
Here ID is the primary key and KeyID contains the parent ID of the item. 这里的ID是主键,而KeyID包含该项的父ID。 KeyLevel contains the level of the node in the hierarchical tree. KeyLevel包含层次结构树中节点的级别。 I have to set the COMBasis property for all the children if the parent's property is changed. 如果更改了父级的属性,则必须为所有子级设置COMBasis属性。 How can I get the children? 我怎样才能得到孩子?
Following is what I am already doing but I am stuck in the after KeyLevel part: 以下是我已经在做的事情,但是我陷入了KeyLevel之后的问题:
foreach (Products prod in ProductList.Where(x => x.KeyID == prd.ID))
{
while(prod.KeyLevel!=6)
prod.COMStandard = prd.COMStandard;
}
So you just need to put that in a recursive function. 因此,您只需要将其放在递归函数中即可。 Something like this: 像这样:
void ApplyCOMBasis(List<Products> productList, int pId, string comStandard)
{
foreach (Products prod in productList.Where(x => x.KeyID == pId))
{
prod.COMStandard = comStandard;
ApplyCOMBasis(productList, prod, comStandard);
}
}
Which you can then call like this (based on your current code): 然后您可以像这样调用它(基于当前代码):
ApplyCOMBasis(ProductList, prd.ID, prd.COMBasis);
In general case , if you have to work a lot with such a graph, I suggest implementing a BFS ( Breadth First Search ) algorithm: 通常 ,如果您需要处理大量此类图,建议您实施BFS ( 广度优先搜索 )算法:
public static IEnumerable<T> BreadthFirst<T>(this IEnumerable<T> source,
Func<T, IEnumerable<T>> children) {
if (Object.ReferenceEquals(null, source))
throw new ArgumentNullException(nameof(source));
else if (Object.ReferenceEquals(null, children))
throw new ArgumentNullException(nameof(children));
HashSet<T> proceeded = new HashSet<T>();
Queue<IEnumerable<T>> queue = new Queue<IEnumerable<T>>();
queue.Enqueue(source);
while (queue.Count > 0) {
IEnumerable<T> src = queue.Dequeue();
if (Object.ReferenceEquals(null, src))
continue;
foreach (var item in src)
if (proceeded.Add(item)) {
yield return item;
queue.Enqueue(children(item));
}
}
}
Having BFS implemented, all you have to do is to specify initial nodes and a rule how to obtain children for a given node: 实施BFS后 ,您要做的就是指定初始节点以及如何为给定节点获取子代的规则 :
var products = ProductList
.Where(prd => prd.ID == ...) // initial nodes
.BreadthFirst(parent => ProductList.Where(item => item.ID == parent.KeyID));
foreach (Products prod in products) {
...
}
Assumping you just have a flat List<Products>
and you need to search it as a hierarchy, you'll need a recursive call. 假设您只有一个平面List<Products>
并且需要按层次结构进行搜索,则需要递归调用。
void UpdateChildren(List<Products> list, int keyId, string value)
{
// find the items with this KeyID
var children = list.Where(i => i.KeyId = keyId)
foreach(var p in children)
{
p.COMBasis = value;
UpdateChildren(list, p.ID, value);
}
}
So when you need to update the parent you start like this 因此,当您需要更新父级时,您将像这样开始
var item = list.Single(x => x.ID = id); // assume you know the id of the parent
item.COMBasis = newCOMBasis;
UpdateChildren(item, item.ID, newCOMBasis);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.