2014-01-23 69 views
1

让所有子元素我在SQL中有一个机构表结构像下面LINQ查询通过传递父ID

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”,那么我应该得到所有childagencies,孙子代理,孙子代理等等,从机构id派生7.对于代理机构标识为“7”,结果集将如下所示

AGENCY_ID AGENCY_NAME PARENT_AGENCY_ID 
    7   yyyyy 2  
    9   aaaa  1  
    1   cccc  7  
    3   eeeee 1  
    5   ggggg 9 

我该如何在linq查询中实现这一点?

+0

这将需要一点递归,这通常不是最佳的,在其上添加一层LINQ可能会让它更慢。我的建议是直接在SQL中执行此操作,并将其公开为可从应用程序代码调用的SP。 – James

+0

这些递归层次结构是Common Table Expressions(CTE)的常用示例。看到这篇文章 - 它有一个类似的例子:http://blog.sqlauthority.com/2008/07/28/sql-server-simple-example-of-recursive-cte/ –

+0

如果不是在linq中,你能帮我吗在写sql存储过程来实现这个! – subash

回答

1

你写在下面的方式递归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(); 
} 

但是,它很可能是更具可读性和简单的编写做同样的事情递归方法。

1

这将需要一点递归,这通常不是最佳的,在其上添加一层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 
} 

看到它in action一样简单。