[英]linq query to get all child elements by passing parent id
我在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 fffff 2
5 ggggg 9
我想要一个LINQ查询来获取结果集,这样当我通过代理商ID时,我应该获得从代理商衍生的所有子代理商
例如,如果我将参数代理商ID传递为“ 7”,那么我应该从代理商ID 7中获得所有后代,孙代代理商,曾孙代代代理商等等。对于代理商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();
}
但是,编写执行相同操作的递归方法可能更易读和更简单。
这将需要一些递归,这通常不是最佳选择,在此之上添加LINQ层可能会使其变得更慢。 我的建议是直接在SQL中执行此操作,并将其公开为SP,您可以从应用程序代码中调用它。
就SP的外观而言,可以使用CTE来实现,例如
CREATE PROCEDURE GetAssociatedAgencies
(
@AgencyID int
)
AS
BEGIN
SET NOCOUNT ON;
WITH cte AS
(
SELECT T1.* FROM Agencies as T1
WHERE AGENCY_ID = @AgencyID
UNION ALL
SELECT T2.* FROM Agencies as T2
INNER JOIN cte AS C on T2.PARENT_AGENCY_ID = C.AGENCY_ID
)
SELECT * FROM cte;
END
通常将存储过程作为方法添加到您的上下文中,因此这就像调用一样简单
using (var context = new MyDataContext())
{
var results = context.GetAssociatedAgencies(7);
// query results
}
看到它在行动 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.