Проблема иерархии LINQ to SQL - PullRequest
       2

Проблема иерархии LINQ to SQL

0 голосов
/ 23 декабря 2010

Я получаю результат из SQL Server как

ProjectDetailID,ProjectID,ParentID,...,C1,C2,C3,...

, где C1 подразумевает (=>) companyOne, C2 => CompanyTwo ... и т. Д., И динамически может иметь 'n' компаний

На данный момент давайте рассмотрим только 3 компании, поэтому я получаю:

ProjectDetailID,ProjectID,ParentID,C1,C2,C3
10,1,0,NULL,NULL,NULL
10,2,1,NULL,NULL,NULL
10,3,2,90,NULL,NULL
10,4,2,NULL,60,NULL
10,10,1,70,NULL,NULL
10,5,10,20,40,NULL
10,13,2,NULL,NULL,NULL

Я хочу получить следующий результат, используя LINQ (C #)

ProjectDetailID,ProjectID,ParentID,C1,C2,C3
10,1,0,180,100,NULL
10,2,1,90,60,NULL
10,3,2,90,NULL,NULL
10,4,2,NULL,60,NULL
10,10,1,90,40,NULL
10,5,10,20,40,NULL
10,13,2,NULL,NULL,NULL

Проблема в том, что на родительском уровнеУ меня есть нулевое значение для компании, но у ее ребенка есть некоторая ценность, которую я продолжаю добавлять и помещаю в родительский объект, соответствующий только этой компании.

Я не понимаю, с чего начать.Пожалуйста, поделитесь своими идеями.И я хочу сделать это в LINQ, используя C #

1 Ответ

3 голосов
/ 29 декабря 2010

Я думаю, что у меня есть решение вашей проблемы.

Я предположил, что класс Project имеет конструктор, который позволяет мне сделать это:

var projects = new List<Project>(new []
{
    new Project(10, 1, 0, null, null, null),
    new Project(10, 2, 1, null, null, null), 
    new Project(10, 3, 2, 90, null, null), 
    new Project(10, 4, 2, null, 60, null), 
    new Project(10, 10, 1, 70, null, null), 
    new Project(10, 5, 10, 20, 40, null), 
    new Project(10, 13, 2, null, null, null), 
});

Итакрешение выглядит так:

var traverse = projects.ToLookup(p => p.ParentID);

Func<Project, Func<Project, int?>, int?> rollup = null;

rollup = (p, f) =>
{
    var result = (f(p) ?? 0) + traverse[p.ProjectID].Sum(p2 => rollup(p2, f));
    return result == 0 ? (int?)null : result;
};

var query = 
    projects.Select(p =>
        new Project(
            p.ProjectDetailID,
            p.ProjectID,
            p.ParentID,
            rollup(p, p2 => p2.C1),
            rollup(p, p2 => p2.C2),
            rollup(p, p2 => p2.C3)));

Хитрость к этому запросу - рекурсивное определение rollup.Чтобы это работало, анонимная функция должна быть объявлена ​​и определена с помощью двух операторов (т.е. определение не может быть встроенным).

Результат соответствует вашему второму набору данных в вашем вопросе.Надеюсь, это то, что вы ищете.

...