C# 如何避免在linq序列concat中更改顺序

C# 如何避免在linq序列concat中更改顺序,c#,linq,sql-order-by,sequence,concat,C#,Linq,Sql Order By,Sequence,Concat,我有两个用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.

我有两个用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] });
然后我想将它们连接起来,得到一个新的序列,如下所示:

var concatSeq = seqA .Concat(seqB);
{a1,a2,a3,…,b1,b2,b3,…}

在实际情况中,第一个序列(此处为seqA)有一个元素,第二个序列(此处为seqB)有多个元素。我确实是这样连接的:

var concatSeq = seqA .Concat(seqB);

我得到了串联序列,但结果只是改变了第二个序列的排序顺序(这里是seqB)。我不知道为什么会发生这种奇怪的行为?

因为
seqA
seqB
都是
IQueryable
,调用的
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
直接循环第一个列表,按顺序返回每个项目,然后对第二个列表执行相同的操作。您可以在中看到这一点。

听起来像是两个查询和您的
Concat
同时被评估,而不是单独评估。如果是这种情况,那么在连接它们之前,先了解
seqA
seqB
。@DavidG理论上你是对的。正如我所说,我对这种奇怪的行为感到惊讶。@JSteward我用AsEnumerable()实现了序列,然后将它们连接起来。concat的结果与之前一样更改了seqB元素的顺序。您是如何使用
AsEnumerable
?如果他们是可质疑的,这可能很重要。@david你说得对。从记录之间具有父/子关系的表中加载序列。seqA有父项,我希望位于结果序列的第一个位置,而seqB有子元素。我想在concat之后保留子元素的顺序。这是一个简单的场景说明。我不能上传一个巨大的.net项目的一部分,但是如果你需要更多的描述,我必须用SQL和.net FIDLE创建一些代码片段。谢谢,达德。很抱歉我迟到了。我需要一个紧急的解决方案,并在我没有找到可用的解决方案后发布这个问题,但在与@DavidG讨论后,我发现这可能比我想象的更奇怪,所以我尝试了一个express cafe解决方案并解决了我的问题,因为Seka只有一个元素。我需要找到一个更好的解决方案,因为其他问题在Seka中可能有更多的元素,而且,我很想知道[在我看来]奇怪的事情为什么会发生?大约一周前,我遇到了一种顽固的细菌,今天我可以袖手旁观,检查这篇文章。我脑子里浮现的一件事是,我在seqB之后用AsQuaryable()测试了同步解决方案(因为我刚才说的seqA中只有一个元素),但不起作用。现在,我应该回到我的床上恢复;但我会在第一个工作日检查,并写下结果和我学到的:)再次感谢。