我有一个带有 WHERE IN (ids) 的 IQueryable。 ToList() return 可以和ids一样的顺序吗?

I have an IQueryable with WHERE IN (ids). Can ToList() return the same order as ids?

我的代码:

var ids = new int[] { 16259,16238,16240,16243 };
var teamQuery = _teamRepository.Where(team => ids.Contains(team.ID));
var teams = teamQuery.ToList();

我有一个 IQueryable 对象 teamQuery,它形成一个查询

SELECT
    [Extent1].[ID] AS [ID],
    [Extent1].[Name] AS [Name],
    FROM [dbo].[Team] AS [Extent1]
    WHERE [Extent1].[ID] IN (16259, 16238, 16240, 16243)

在 ToList() 实现期间,我能否在生成的列表 teams 对象中保持与 IN 方法中相同的顺序(16259、16238、16240、16243)?

现在 teams 中对象的顺序是 [16238, 16240, 16243, 16259]

这是您想要尝试并近似的 SQL:

SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
FROM [dbo].[Team] AS [Extent1]
WHERE [Extent1].[ID] IN (16259, 16238, 16240, 16243)
ORDER BY CASE [Extent1].ID 
             WHEN 16259 THEN 0
             WHEN 16238 THEN 1
             WHEN 16240 THEN 2
             WHEN 16243 THEN 3
             ELSE 4
         END;

我不推荐将此作为通用解决方案,除非您的选项列表被限制为非常小:

var ids = new [] { 16259, 16238, 16240, 16243 };
var firstId = ids.First();
var teamQuery = _teamRepository.Where(team => ids.Contains(team.ID))
                               .OrderByDescending(t => t.Id == firstId);
foreach(var id in ids.Skip(1))
{
    teamQuery = query.ThenByDescending(t => t.Id == id);
}
var teams = teamQuery.ToList();

一个更有效的解决方案是通过与原始数组索引相关联来对在数据库中执行之后的结果进行排序:

var ids = new [] { 16259, 16238, 16240, 16243 };
var teamData = _teamRepository.Where(team => ids.Contains(team.ID)).ToList();
var teams = teamData.OrderBy(team => ids.IndexOf(team.ID)).Tolist();

要在纯 SQL 中高效地完成大型列表,首先需要创建有序列表作为 table 引用,然后您可以按该列表中的位置排序,但 LINQ到 SQL 不会轻易复制相同的过程,除非您在架构中定义特定的 用户定义类型

您也可以插入这种类型的查询,或将其构建为原始 SQL,这为您提供了更多选项,但更少 LINQish。

通常我们可以使用更高效的 C# 代码以这些自定义方式对数据进行排序。除非列表非常大,否则对数据库进行排序的好处很少。