2014-01-23 84 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一樣簡單。