Поддержание порядка при выборе статической группы из таблицы - PullRequest
3 голосов
/ 17 декабря 2010

Скажем, у меня есть статический список идентификаторов в определенном порядке:

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 ]

3 голосов
/ 17 декабря 2010

Если вы явно не включаете предложение order-by, у вас действительно есть только set - любое упорядочивание чисто удобное и обычно оказывается в кластерном индексе- но IIRC это не гарантируется (и я полагаю, что такие вещи, как сервер, выбравший параллелизм, будут выбрасывать это)

Включить упорядочение;либо на БД, либо на клиенте.В качестве альтернативы, выбросьте результаты в словарь:

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

, затем вы можете извлечь тот, который вам нужен, игнорируя порядок.

1 голос
/ 19 декабря 2010

Вот комбинация ответа Марка и вашего ответа:

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

Поскольку он пропускает шаг OrderBy, я подозреваю, что он будет немного более эффективным.Это, конечно, немного красивее.

1 голос
/ 19 декабря 2010

В итоге мы получили:

        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();

Уродливо, но достаточно эффективно для больших списков.

0 голосов
/ 17 декабря 2010

Вы можете проецировать 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...