排序列中具有重复值的 LINQ to SQL SkipWhile 实现

发布于 2025-01-08 09:14:54 字数 1498 浏览 5 评论 0原文

我有一个按评分降序排序的文章列表。如果评级相同,则按ID升序排序(ID是唯一的):

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

我想查询3篇文章的页面,这意味着第一页将有文章9、3和6。这是通过查询顶部来完成的3 篇文章构成排序列表。

现在,我想从第 8 篇文章中恢复接下来的 3 篇文章,使用文章 ID 作为恢复位置的标记,而不是仅仅跳过前 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);

但 LINQ to SQL 中未实现 SkipWhile(请参阅 此处)。

如果我这样做:

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,使用文章 ID 作为恢复位置的标记来恢复第 8 篇文章的分页的最佳方法是什么?

I have a list of articles sorted by descending rating. If the rating is the same, they are sorted by ascending ID (the IDs are unique):

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

I want to query pages of 3 articles, which means the first page will have articles 9, 3 and 6. This is done by querying the top 3 articles form the sorted list.

Now, I want to take the next 3 articles resuming from article 8, using the article ID as marker for where to resume, as opposed to just skipping the first 3 articles. This is because the content of the article table changes very rapidly and a standard pagination approach like this:

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

would not work reliably because articles can be added or deleted at any time (just assume the rating doesn't change here).

If this was LINQ to Object, I could use SkipWhile:

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

but SkipWhile is not implemented in LINQ to SQL (see here).

If I did like this:

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

I would skip article 12, while if I did something like this:

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

I would take articles 3 and 6 twice.

Using LINQ to SQL, what's the best way to resume the pagination from article 8, using the article ID as marker for where to resume?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

喜爱纠缠 2025-01-15 09:14:54

你可以这样做吗:

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;
    }

我认为这可以解决问题。

Can you just do:

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

Okay, if that won't work, I'd write a function something like this:

    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;
    }

which I think will do the trick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文