LINQ to SQL Реализация SkipWhile с дублирующимися значениями в столбце сортировки - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть список статей, отсортированных по убыванию рейтинга.Если рейтинг одинаковый, они сортируются по возрастанию идентификатора (идентификаторы уникальны):

ID      RATING
9       34
3       32
6       32
8       32
12      32
1       25
2       23

Я хочу запросить страницы из 3 статей, что означает, что на первой странице будут статьи 9, 3 и6. Это делается путем запроса 3 верхних статей из отсортированного списка.

Теперь я хочу взять следующие 3 статьи, начиная со статьи 8, используя идентификатор статьи в качестве маркера для возобновления, в отличие отпросто пропустить первые 3 статьи.Это связано с тем, что содержание таблицы статей изменяется очень быстро, и стандартный подход разбивки на страницы, такой как:

var articles = 
    db.Articles
    .OrderByDescending(a => a.Rating).ThenBy(a => a.Id)
    .Skip(3)
    .Take(3);

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

Если бы это было LINQ to Object, я мог бы использовать SkipWhile:

var articles = 
    db.Articles
    .OrderByDescending(a => a.Rating).ThenBy(a => a.Id)
    .SkipWhile(a => a.Article.Id != 8)
    .Take(3);

, но SkipWhile не реализовано в LINQ to SQL (см. здесь ).

Если бы я сделал так:

var articles = 
    db.Articles
    .Where(a => a.Rating 
             < db.Articles.Single(aa => aa.Id == 8).Rating)
    .OrderByDescending(a => a.Rating)
    .Take(3);

Я бы пропустил статью 12, а если бы сделал что-то вроде этого:

var articles = 
    db.Articles
    .Where(a => a.Rating 
             <= db.Articles.Single(aa => aa.Id == 8).Rating)
    .OrderByDescending(a => a.Rating)
    .Take(3);

Я бы взял статьи 3 и 6 дважды.

Используя LINQ to SQL, каков наилучший способ возобновить нумерацию страниц из статьи 8, используя идентификатор статьи в качестве маркера для того, где продолжить?

1 Ответ

1 голос
/ 22 февраля 2012

Можете ли вы просто сделать:

var articles = 
db.Articles
.OrderByDescending(a => a.Rating).ThenBy(a => a.Id)
.Skip(3)
.Take(3);

Хорошо, если это не сработает, я напишу функцию примерно так:

    static IEnumerable<Article> GetArticles(List<Article> articles, int articlesToRetrieve, int startingID)
    {
        IEnumerable<Article> results = null;
        results = articles.OrderByDescending(a => a.Rating).ThenBy(a => a.ID);

        if (startingID > 0)
        {
            int lastRating = articles.Single(aa => aa.ID == startingID).Rating;
            results = results.Where(a => a.Rating < lastRating || (a.Rating == lastRating && a.ID > startingID));
        }

        if (articlesToRetrieve > 0)
        {
            results = results.Take(articlesToRetrieve);
        }
        return results;
    }

, что, я думаю, подойдеттрюк.

...