说我有一个特定顺序的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();
快速恢复,但无序。
如何从数据库中选择这些帖子并以优雅高效的方式维护订单?
答案 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();