从表中选择静态组时维护顺序

时间:2010-12-17 06:01:57

标签: c# linq linq-to-sql

说我有一个特定顺序的ID列表静态列表:

List<int> ordered = new List<int> {7,2,3,4,5};

我想从数据库中选择维护该顺序的项目。

琐碎:

 var posts = ( from p in Current.DB.Posts
                        where ordered.Contains(p.Id)
                        select p).ToList();

快速恢复,但无序。

如何从数据库中选择这些帖子并以优雅高效的方式维护订单?

4 个答案:

答案 0 :(得分:3)

如果你没有明确地包含一个order-by子句,你只有一个 set - 任何排序都是纯粹的方便,通常碰巧在聚集索引 - 但IIRC这是不能保证的(我想像选择使用并行性的服务器就会抛出这个)

包含订单;无论是在DB还是在客户端。或者,将结果放入字典中:

var dict = Current.DB.Posts.Where(p => ordered.Contains(p.Id))
                  .ToDictionary(p => p.Id);

然后你可以随意拿出你需要的那个,忽略顺序。

答案 1 :(得分:1)

我们最终选择了:

        var reverseIndex = ordered.Select((id, index) => new { Id = id, Index = index }).ToDictionary(pair => pair.Id, s => s.Index);

        model.Posts = Current.DB.Posts
            .Where(p => postIds.Contains(p.Id))
            .AsEnumerable()
            .OrderBy(p => reverseIndex[p.Id] )
            .ToList();

丑陋但对大型列表而言相当有效。

答案 2 :(得分:1)

以下是Marc的答案和你的答案的组合:

var dict = Current.DB.Posts.Where(p => ordered.Contains(p.Id))
           .ToDictionary(p => p.Id);
return ordered.Select(id => dict[id]).ToList();

由于它省略了OrderBy步骤,我怀疑它会更有效率。它当然有点漂亮。

答案 3 :(得分:0)

您可以将List<int>投射到您的帖子列表中。

var posts = ( from p in Current.DB.Posts 
                        where ordered.Contains(p.Id) 
                        select p).ToList(); 

return ordered.Select(o => posts.Single(post => post.Id == o)).ToList();

您也可以在数据库检索级别执行此操作,但您要执行多个select语句

ordered.Select(o => Current.DB.Posts.Single(post => post.Id == o)).ToList();