LINQ Concat сортировка вложенных запросов - PullRequest
1 голос
/ 26 мая 2019

У меня есть следующий код:

var comp = db.Companies.Select(x => new
        {

            topid = x.ID_comp,
            hill = ((from company in db.Companies
                    where x.ID_comp > company.ID_comp
                    orderby company.ID_comp
                    select new { h = company.ID_comp.ToString() })
                    .Concat((
                    from company in db.Companies
                    where x.ID_comp > company.ID_comp
                    orderby company.ID_comp descending
                    select new { h = company.ID_comp.ToString() })))
                    .Select(y => y.h)
        });

Задача состоит в том, чтобы построить «пирамиды» идентификаторов для идентификатора каждой компании: 121 для 3, 12321 для 4 и т. Д. (Если есть компании с идентификаторами, такими как 1, 2, 3 4 ). Идея данного запроса состоит в том, чтобы взять все идентификаторы, которые меньше текущих в 2 наборах, и затем объединить их, упорядочив второй набор в порядке убывания (вершина пирамиды дублируется, но я вернусь к нему позже).

Проблема в том, что предложение order by не выполняется для каждого набора в отдельности, и в конце я получаю что-то вроде 1 2 3 1 2 3 для компании с идентификатором 4. Как я могу заказать вложенные запросы в разных заказах?

UPD1: данные, с которыми я работаю:

Таблица db.Companies

ID_comp | name
--------------------
   1    |Don_avia  
   2    |Aeroflot  
   3    |Dale_avia 
   4    |air_France
   5    |British_AW

Выход:

1:
2: 1 1
3: 1 2 1 2
4: 1 2 3 1 2 3
5: 1 2 3 4 1 2 3 4

UPD2: Результирующий запрос:

SELECT 
[Extent1].[ID_comp] AS [ID_comp], 
[Project3].[C2] AS [C1], 
[Project3].[C1] AS [C2]
FROM  [dbo].[Company] AS [Extent1]
OUTER APPLY  (SELECT 
    [UnionAll1].[C1] AS [C1], 
    1 AS [C2]
    FROM  (SELECT 
         CAST( [Extent2].[ID_comp] AS nvarchar(max)) AS [C1]
        FROM [dbo].[Company] AS [Extent2]
        WHERE [Extent1].[ID_comp] > [Extent2].[ID_comp]
    UNION ALL
        SELECT 
         CAST( [Extent3].[ID_comp] AS nvarchar(max)) AS [C1]
        FROM [dbo].[Company] AS [Extent3]
        WHERE [Extent1].[ID_comp] > [Extent3].[ID_comp]) AS [UnionAll1] ) AS [Project3]
ORDER BY [Extent1].[ID_comp] ASC, [Project3].[C2] ASC

Ответы [ 2 ]

2 голосов
/ 26 мая 2019

Похоже, вы столкнулись с ошибкой перевода запроса EF6 - упорядочение подзапросов .Concat (SQL UNION ALL) игнорируется.

Обходной путь, который я нашел, заключается в добавлении ложного ограничивающего оператора, например Take(int.MaxValue), к подзапросам, что заставляет EF6 учитывать порядок:

hill =
    (from company in db.Companies
     where x.ID_comp > company.ID_comp
     orderby company.ID_comp
     select new { h = company.ID_comp.ToString() }
    ).Take(int.MaxValue)
    .Concat(
    (from company in db.Companies
     where x.ID_comp > company.ID_comp
     orderby company.ID_comp descending
     select new { h = company.ID_comp.ToString() }
    ).Take(int.MaxValue))
    .Select(y => y.h)

Сгенерированный SQL:

SELECT
    [Extent1].[ID_comp] AS [ID_comp],
    [Project5].[C2] AS [C1],
    [Project5].[C1] AS [C2]
    FROM  [dbo].[Company] AS [Extent1]
    OUTER APPLY  (SELECT
        [UnionAll1].[C1] AS [C1],
        1 AS [C2]
        FROM  (SELECT TOP (2147483647)
            [Project1].[C1] AS [C1]
            FROM ( SELECT
                [Extent2].[ID_comp] AS [ID_comp],
                 CAST( [Extent2].[ID_comp] AS nvarchar(max)) AS [C1]
                FROM [dbo].[Company] AS [Extent2]
                WHERE [Extent1].[ID_comp] > [Extent2].[ID_comp]
            )  AS [Project1]
            ORDER BY [Project1].[ID_comp] ASC
        UNION ALL
            SELECT TOP (2147483647)
            [Project3].[C1] AS [C1]
            FROM ( SELECT
                [Extent3].[ID_comp] AS [ID_comp],
                 CAST( [Extent3].[ID_comp] AS nvarchar(max)) AS [C1]
                FROM [dbo].[Company] AS [Extent3]
                WHERE [Extent1].[ID_comp] > [Extent3].[ID_comp]
            )  AS [Project3]
            ORDER BY [Project3].[ID_comp] DESC) AS [UnionAll1] ) AS [Project5]
    ORDER BY [Extent1].[ID_comp] ASC, [Project5].[C2] ASC
0 голосов
/ 26 мая 2019
var comp = db.Companies.Select(x => new
{
    topid = x.ID_comp,
    hill = ((from company in db.Companies.OrderBy(y => y.ID_comp)
        where x.ID_comp > company.ID_comp
        select new { h = company.ID_comp.ToString() })
        .Concat((
        from company in db.Companies.OrderByDescending(y => y.ID_comp)
        where x.ID_comp > company.ID_comp
        select new { h = company.ID_comp.ToString() })))
        .Select(y => y.h)
    });
...