C# 通过传递父id获取所有子元素的linq查询
我在sql中有一个代理表结构,如下所示C# 通过传递父id获取所有子元素的linq查询,c#,linq,C#,Linq,我在sql中有一个代理表结构,如下所示 AGENCY_ID AGENCY_NAME PARENT_AGENCY_ID 7 yyyyy 2 8 xxxx 0 9 aaaa 1 6 bbbb 0 1 cccc 7 2 ddddd 0 3 eeeee 1 4
AGENCY_ID AGENCY_NAME PARENT_AGENCY_ID
7 yyyyy 2
8 xxxx 0
9 aaaa 1
6 bbbb 0
1 cccc 7
2 ddddd 0
3 eeeee 1
4 fffff 2
5 ggggg 9
我想要一个LINQ查询以这样的方式获得结果集:当我传递一个代理id时,我应该获得从该代理派生的所有子代理
例如,如果我将参数agency id传递为“7”,那么我应该获得从agency id 7派生的所有子agency、孙子agency、曾孙agency等。对于agency id为“7”,结果集如下所示
AGENCY_ID AGENCY_NAME PARENT_AGENCY_ID
7 yyyyy 2
9 aaaa 1
1 cccc 7
3 eeeee 1
5 ggggg 9
如何在linq查询中实现这一点?您可以按照以下方式编写递归lambda表达式,并利用linq:
public class Agency
{
public int Id {get; set;}
public int ParentId {get; set;}
public string Name {get; set;}
}
void Main()
{
var list = new List<Agency> {
new Agency { Id = 7, ParentId = 2},
new Agency { Id = 8, ParentId = 0},
new Agency { Id = 9, ParentId = 1},
new Agency { Id = 6, ParentId = 0},
new Agency { Id = 1, ParentId = 7},
new Agency { Id = 2, ParentId = 0},
new Agency { Id = 3, ParentId = 1},
new Agency { Id = 4, ParentId = 2},
new Agency { Id = 5, ParentId = 9}
};
Func<Agency,int, bool> isParent = null;
isParent = (a,i) => a != null &&
(a.Id == i || isParent(list.FirstOrDefault(x => x.Id == a.ParentId),i));
var descendantsOf7 = list.Where(x=>isParent(x,7)).ToList();
}
公共类代理
{
公共int Id{get;set;}
public int ParentId{get;set;}
公共字符串名称{get;set;}
}
void Main()
{
变量列表=新列表{
新机构{Id=7,ParentId=2},
新机构{Id=8,ParentId=0},
新机构{Id=9,ParentId=1},
新代理{Id=6,ParentId=0},
新机构{Id=1,ParentId=7},
新代理{Id=2,ParentId=0},
新机构{Id=3,ParentId=1},
新机构{Id=4,ParentId=2},
新机构{Id=5,ParentId=9}
};
Func isParent=null;
isParent=(a,i)=>a!=null&&
(a.Id==i | | isParent(list.FirstOrDefault(x=>x.Id==a.ParentId),i));
var descendantsOf7=list.Where(x=>isParent(x,7)).ToList();
}
然而,编写一个做同样事情的递归方法可能会更可读、更简单。这将需要一些递归,这通常不是最优的,在上面添加一层LINQ可能会使它更慢。我的建议是直接在SQL中这样做,并将其作为SP公开,您可以从应用程序代码中调用它 就SP的外观而言,这可以通过使用 存储过程通常作为一种方法添加到您的上下文中,因此这与调用
using (var context = new MyDataContext())
{
var results = context.GetAssociatedAgencies(7);
// query results
}
请看。这将需要一些递归,这通常不是最优的,在其上添加一层LINQ可能会使其更慢。我的建议是直接在SQL中这样做,并将其公开为SP,您可以从应用程序代码中调用它。这些递归层次结构是常用的公共表表达式(CTE)示例。看这篇文章-它有一个类似的例子:如果不是在linq中,你能帮助我编写sql存储过程来实现这一点吗!
using (var context = new MyDataContext())
{
var results = context.GetAssociatedAgencies(7);
// query results
}