2011-02-04 130 views
3

我有興趣編寫IQueryable接口的擴展方法。該方法將遞歸地返回指定選擇器的所有子項。遞歸IQueryable Linq擴展方法

public static class MyExtensions 
{ 
    public static IQueryable<IRecursion<T>> SelectRecursive<T>(this IQueryable<T> source, Func<T, IQueryable<T>> selector) 
    { 
     //Code goes here 
    } 

    public interface IRecursion<T> 
    { 
     int Depth { get; } 

     T Item { get; } 
    } 
} 

實例:由函數生成

var allChildren = tblCompanies 
     .Where(c => c.pkCompanyID == 38) 
     .SelectRecursive(p => tblCompanies.Where (c => c.pkCompanyID == p.fkCompToCompID)); 

SQL代碼將是這樣的。

WITH CompanyCTE(ID, parentID, depth) AS 
(
    SELECT 
     pkCompanyID, 
     fkCompToCompID, 
     0 
    FROM 
     tblCompany 

    UNION ALL 

    SELECT 
     tblCompany.pkCompanyID, 
     tblCompany.fkCompToCompID, 
     CompanyCTE.depth + 1 
    FROM 
     tblCompany 
     JOIN CompanyCTE ON tblCompany.fkCompToCompID = CompanyCTE.ID 
) 
SELECT 
    tblCompany.*, --Item 
    CompanyCTE.depth --Depth 
FROM 
    CompanyCTE 
    JOIN tblCompany ON CompanyCTE.ID = tblCompany.pkCompanyID 
WHERE 
    parentID = 38 

可以這樣做嗎? 如果不能用CTE,可能用SQL 2008 hierarchyid?

回答

1

這L2S是不可能的。但是,如果您足夠了解,則可以將查詢擴展到某個恆定的深度。這將導致一個討厭的連接森林。

由於您的「公司」的集合可能不是很大,請嘗試加載所有這些並在客戶端執行此操作。