Рекурсивный метод IQueryable Linq Extensions - PullRequest
3 голосов
/ 04 февраля 2011

Я заинтересован в написании метода расширения интерфейса IQueryable. Метод возвращает все дочерние элементы рекурсивно указанного селектора.

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?

Ответы [ 2 ]

1 голос
/ 14 сентября 2011

Это невозможно в L2S. Однако вы можете расширить запрос до определенной постоянной глубины, если этого достаточно для вас. Это приведет к неприятному лесу соединений.

Поскольку ваш набор "компаний", вероятно, не очень велик, попробуйте загрузить их все и сделать это на стороне клиента.

0 голосов
/ 04 февраля 2011
...