Как избежать изменения ордеров в последовательности linq concat - PullRequest
0 голосов
/ 11 января 2019

У меня есть две последовательности, определенные с var, как показано ниже:

var seqA = from a in db.aSample
where ([some conditions])
orderby (a.sortOrder)
select new { id = a.id, [... another fields] });

var seqB = from b in db.bSample
where ([some conditions])
orderby (b.sortOrder)
select new { id = b.id, [... another fields] });

Затем я хочу объединить их, чтобы получить новую последовательность, подобную этой:

{a1, a2, a3, ...., b1, b2, b3, ...}

В реальном случае первая последовательность (здесь seqA) имеет один элемент, а вторая последовательность (здесь seqB) имеет много. Я конкатенировал вот так:

var concatSeq = seqA .Concat(seqB);

Я получил сцепленную последовательность, но в результате просто изменил порядки сортировки второй последовательности (здесь seqB). Я не знаю, почему произошло это странное поведение?

1 Ответ

0 голосов
/ 11 января 2019

Поскольку оба значения seqA и seqB равны IQueryable<>, вызываемый метод Concat является System.Linq. Queryable .Concat вместо System.Linq. перечислимых .Concat . Это тонкая разница, но она имеет значение. Запрашиваемая версия выдаст SQL примерно так, обратите внимание, что порядок не указан вообще:

SELECT ...
FROM SomeTable
UNION ALL 
SELECT ...
FROM SomeTable

Вы можете принудительно использовать перечисляемую версию, используя AsEnumerable(). Например:

var concatSeq = seqA.AsEnumerable().Concat(seqB);

Примечание: Не во внутренней последовательности, AsEnumerable должно быть в первой последовательности. Это даст 2 запроса SQL с вашим порядком, что-то вроде:

SELECT ...
FROM SomeTable
ORDER BY SomeColumn

И конкатенация будет выполняться локально в памяти. Перечисляемая версия Concat буквально проходит по первому списку, возвращая каждый элемент по порядку, а затем делает то же самое для второго списка. Вы можете увидеть это в исходном коде .

...