【问题标题】:How to get and select real correct Data Asynchronously up to date如何异步获取和选择真正正确的数据
【发布时间】:2017-10-15 08:48:09
【问题描述】:

在一个网站中,有一个文章页面,当我进入文章页面时,它会显示文章,前10个cmets属于这篇文章。

还有一些按钮,点击后,通过AJAX异步显示所有cmets的其余部分。

问题是假设在文章页面加载前 10 个 cmets 后,拥有评论的用户或管理员删除它, 如何选择其余的cmets? 如果我从 select 语句中跳过前 10 个 cmets,则有一些 cmets 没有被选中。

例如:

假设 cmets ID 是: 1、2、3、4、5、6、7、8、9、10、11、12、13、14、15、16、17、18、19、20

我选择的前 10 个 cmets ID 是:1、2、3、4、5、6、7、8、9、10

IEnumerable<Comment> comments = (from a in context.Comments
                                         where a.ArticleID == ArticleID
                                         orderby a.CommentDate descending
                                         select new Comment
                                         {
                                             CommentID = a.CommentID,
                                             CommentContent = a.CommentContent,
                                             CommentDate = a.CommentDate,


                                         }).ToList().Take(10);

假设拥有评论或管理员的用户删除了 ID 为 9、10 的 2 个 cmets

那么数据库中的前十个 cmets 将变为:1, 2, 3, 4, 5, 6, 7, 8, 11, 12

当我尝试获取其余的 cmets 并跳过前 10 个 cmets 时, 那么结果是:13、14、15、16、17、18、19、20

IEnumerable<Comment> comments = (from a in context.Comments
                                         where a.ArticleID == ArticleID
                                         orderby a.CommentDate descending
                                         select new Comment
                                         {
                                             CommentID = a.CommentID,
                                             CommentContent = a.CommentContent,
                                             CommentDate = a.CommentDate,


                                         }).ToList().Skip(10);

所以有两个 cmets 11 和 12 我看不到它们,因为 ID 为 11、12 的 cmets 将与前 10 个 cmets 一起考虑...

【问题讨论】:

  • 那么这里的预期是什么......你想要 11,12 在这两个集合中,即前 10 个以及其余的所有?
  • 你明白我的问题吗???

标签: javascript c# design-patterns asp.net-core asp.net-core-mvc


【解决方案1】:

您需要在同一个 LINQ 查询中使用 Skip 和 Take together,并且传递给这些函数的值应该是动态的,基于应用程序中已经呈现的数据。

因此,对于初始页面显示,您将有这样的查询:

var toSkip = 0; var toTake = 10;

IEnumerable<Comment> comments = (from a in context.Comments
    where a.ArticleID == ArticleID
    orderby a.CommentDate descending
    select new Comment
    {
        CommentID = a.CommentID,
        CommentContent = a.CommentContent,
        CommentDate = a.CommentDate
    })
    .Skip(toSkip).Take(toTake).ToList();

后续查询将适当更改 toSkiptoTake 变量中的值。 理想情况下,这些将是发送到 MVC 操作的参数,用于获取应用程序所需的数据。

使用这种方法,您将需要有一种方法来根据先前或初始列表中留下的数据来判断要跳过多少。一个 LINQ 查询根据当前列表中的 Min 和 Max 注释 Id 获取项目计数,应该允许您导出要跳过的数字。此查询也会考虑在请求之间删除的数据。这似乎是一个额外的查询,所以我对此并不感到兴奋。

您可以使用先前列表中的 MAX 评论 ID,并像这样进行过滤。

var toTake = 10; var maxCommentId = 10;

IEnumerable<Comment> comments = (from a in context.Comments
    where a.ArticleID == ArticleID
    && a.CommentID > maxCommentId // <- new filter here
    orderby a.CommentDate descending
    select new Comment
    {
        CommentID = a.CommentID,
        CommentContent = a.CommentContent,
        CommentDate = a.CommentDate
    })
    .Take(toTake).ToList();

同样,变量值需要根据当前应用程序状态进行更改;使它们的动作参数变得理想。像这样的:

public async IActionResult GetComments(int articleID,
  int toSkip = 0,
  int toTake = 10)
    {
        IEnumerable<Comment> comments = (from a in context.Comments
          where a.ArticleID == articleID
          orderby a.CommentDate descending
          select new Comment
          {
              CommentID = a.CommentID,
              CommentContent = a.CommentContent,
              CommentDate = a.CommentDate
          })
          .Skip(toSkip).Take(toTake).ToList();
        return comments;
    }

这不是一个完整的解决方案,但它应该让您了解采取最适合您的应用程序的方向。希望对你有帮助。

【讨论】:

  • 谢谢,我之前想过这个,但是假设管理员删除评论 ID = 8,我设置最大 ID =10,那么 ID = 8 现在是免费的,假设另一个用户添加新评论,所以这个新评论可能会说 ID = 8,因为这个号码现在是免费的,所以不会出现 ID = 8 的新评论
  • 这让我觉得你永远不应该跳过任何东西,只需增加每个后续查询的 Take,然后每次都在 UI 中完全重新填充列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多