2011-02-04 161 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是不可能的。但是,如果您足够了解,则可以将查询扩展到某个恒定的深度。这将导致一个讨厌的连接森林。

由于您的“公司”的集合可能不是很大,请尝试加载所有这些并在客户端执行此操作。