Algorithm 如何有效地建立一个;“得到后代”;linq到实体的算法?
在下面这样一个树中,每个项目只知道其父id和订单号,有什么好方法可以查询Foo的所有后代Algorithm 如何有效地建立一个;“得到后代”;linq到实体的算法?,algorithm,linq,linq-to-entities,Algorithm,Linq,Linq To Entities,在下面这样一个树中,每个项目只知道其父id和订单号,有什么好方法可以查询Foo的所有后代 1:Foo 2:孩子 3:孙女1 4:孙子2 5:酒吧 6:Baz 我可以得到这样的孩子 var q = from item in foos where item.parentid == "Foo" select item; 但是,如何在一个查询中获得任意深度的所有子体?如果可能的话,我希望避免使用多个查询进行递归。具体来说,我想得到所有可能的后代,不仅仅是孩子
- 1:Foo
- 2:孩子
- 3:孙女1
- 4:孙子2
- 2:孩子
- 5:酒吧
- 6:Baz
var q = from item in foos
where item.parentid == "Foo"
select item;
但是,如何在一个查询中获得任意深度的所有子体?如果可能的话,我希望避免使用多个查询进行递归。具体来说,我想得到所有可能的后代,不仅仅是孩子和孙子,还有N级的孩子。我想我可以使用订单号,比如这个案例和一个查询,比如
var q = from item in foos
where item.ordernumber > 1 && item.ordernumber < 5
select item;
var q=来自foos中的项
其中item.ordernumber>1&&item.ordernumber<5
选择项目;
但是在这种情况下,我不知道如何获得5
,这意味着下一个非后代订单号。此时总是知道1
编辑:添加了被遗忘的细节,我希望它选择所有后代,而不仅仅是孩子和孙子。
公共类元素
public class Element
{
public int ID { set; get; }
public string Name { get; set; }
public List<Element> Children { get; set; }
}
static void Main(string[] args)
{
List<Element> elements = new List<Element>();
Element Foo = new Element() { ID = 1, Name = "Foo" };
Element Child = new Element() { ID = 2, Name = "Child" };
Element GrandChild1 = new Element() { ID = 3, Name = "GrandChild 1" };
Element GrandChild2 = new Element() { ID = 4, Name = "GrandChild 2" };
Element Bar = new Element() { ID = 5, Name = "Bar" };
Element Baz = new Element() { ID = 6, Name = "Baz" };
Foo.Children = new List<Element>();
Foo.Children.Add(Child);
Child.Children = new List<Element>();
Child.Children.Add(GrandChild1);
Child.Children.Add(GrandChild2);
elements.Add(Foo);
elements.Add(Bar);
elements.Add(Baz);
var query = elements.Where(e => e.Name == "Foo").SelectMany(c => c.Children);
var query2 = query.Union(query.SelectMany(g => g.Children));
foreach (var item in query2)
{
Console.WriteLine(item.Name);
}
}
{
公共int ID{set;get;}
公共字符串名称{get;set;}
公共列表子项{get;set;}
}
静态void Main(字符串[]参数)
{
列表元素=新列表();
元素Foo=newelement(){ID=1,Name=“Foo”};
Element Child=new Element(){ID=2,Name=“Child”};
元素孙子1=新元素(){ID=3,Name=“孙子1”};
元素孙子2=新元素(){ID=4,Name=“孙子2”};
Element Bar=new Element(){ID=5,Name=“Bar”};
Element Baz=new Element(){ID=6,Name=“Baz”};
Foo.Children=新列表();
Foo.Children.Add(Child);
Children.Children=新列表();
Child.Children.Add(1);
Child.Children.Add(孙子2);
元素。添加(Foo);
元素。添加(条);
增加(Baz);
var query=elements.Where(e=>e.Name==“Foo”).SelectMany(c=>c.Children);
var query2=query.Union(query.SelectMany(g=>g.Children));
foreach(查询2中的var项)
{
Console.WriteLine(项目名称);
}
}
无法找到此问题的答案,因此将我的解决方案放在这里。我使用了一个通过调用递归函数来构建列表的函数。递归函数获取一个id,将具有该id的行添加到一个列表(子体),检查该行的子项,如果有子项,则它启动foreach并为每个子项调用自己,传递子项的id:
public List<WikiPageModel> Descendants;
public List<WikiPageModel> GetDescendantsOf(int id)
{
Descendants = new List<WikiPageModel>();
GetDescendantsOf_Recursor(id);
return Descendants;
}
public void GetDescendantsOf_Recursor(int id)
{
var page = WikiPages.FirstOrDefault(x => x.PageId == id);
Descendants.Add(page);
var children = GetChildrenOf(id);
if (children.Any())
{
foreach (var child in children)
{
id = child.PageId;
GetDescendantsOf_Recursor(id);
}
}
}
public List<WikiPageModel> GetChildrenOf(int pageId)
{
return WikiPages.Where(x => x.ParentPageId == pageId).ToList();
}
公共列表子体;
公共列表GetDescendantsOf(int id)
{
子体=新列表();
GetDescendantsOf_递归器(id);
传宗接代;
}
public void getDegenantsOf_递归器(int-id)
{
var page=WikiPages.FirstOrDefault(x=>x.PageId==id);
添加(第页);
var childrenof=GetChildrenOf(id);
if(children.Any())
{
foreach(儿童中的儿童变量)
{
id=child.PageId;
GetDescendantsOf_递归器(id);
}
}
}
公共列表GetChildrenOf(int pageId)
{
返回WikiPages.Where(x=>x.ParentPageId==pageId.ToList();
}
我不确定我是否理解你的问题。你想要foo
的所有子项吗?我想要foo的所有子项,意思是“子、孙1和孙2”,共3项。希望能澄清一些事情。各位用户,如果不清楚,请投票支持@JensKloster的评论,我将编辑这个问题。好的。你能给我看看你的课吗?Foo
,是否有一个Child
集合,还是只有一个。Foo
、Child
、granter1
和granter2
是同一类型吗?这更像是一个关于算法的理论问题:)我可能稍后会做一个例子,但现在:它们都是同一类型,比如说Item
。所有项目都有三个属性,例如string id“Foo”
,string parentid null
和int ordernumber 1
或另一个示例:string id“孙子1”
,string parentid“Child”
和int ordernumber 3
-根本没有其他属性。这个问题看起来确实有点过于理论化,我实际上正在考虑在这一点上删除它,然后解决递归问题……这个方法在第三个级别之后还能工作吗?在我看来,它只是简单地返回子代和孙辈,但并不是所有的N级后代都是无限的。是的,我的要求之一是获得N级物品,这是我问题的真正问题。对不起,如果不清楚的话。我知道我可以使用递归方法,但我只是想避免使用所有这些一次性上下文(我基本上每个方法使用1个上下文)。这也是我最后要做的。如果可能的话,我真的想避免递归,但这似乎是最简单的选择。