【问题标题】:Add Pagination MVC and Azure table storage添加 Pagination MVC 和 Azure 表存储
【发布时间】:2015-02-19 05:55:08
【问题描述】:

我正在尝试将分页应用于我的 MVC 应用程序。我正在使用 Azure 表存储

这是我尝试过的:-

public List<T> GetPagination(string partitionKey, int start, int take)
    {
        List<T> entities = new List<T>();

        TableQuery<T> query = new TableQuery<T>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey.ToLower()));
        entities = Table.ExecuteQuery(query).Skip(start).Take(take).ToList();

        return entities;

    }

控制器:-

public ActionResult Index()
        {

            key= System.Web.HttpContext.Current.Request[Constants.Key];
            if (String.IsNullOrEmpty(key))
                return RedirectToAction("NoContext", "Error");

            var items= _StorageHelper.GetPagination(key,0,3);
           ItemCollection itemCollection = new ItemCollection();
            itemCollection .Items= Mapper.Map<List<ItemChart>, List<ItemModel>>(items);
            itemCollection .Items.ForEach(g => g.Object = g.Object.Replace(key, ""));


            return View(itemCollection);
        }

这目前为我提供了数据中的前 3 个条目。现在如何显示和实现“上一个”和“下一个”以在下一页显示其余条目?如何实现控制器和 HTML 页面的其余部分?

感谢任何帮助。

【问题讨论】:

    标签: asp.net-mvc azure pagination


    【解决方案1】:

    说到分页,有几点需要考虑:

    • 并非所有 LINQ 运算符(以及 OData 查询选项)都支持表服务。例如,不支持 Skip。有关支持的运算符列表,请参阅此链接:https://msdn.microsoft.com/en-us/library/azure/dd135725.aspx
    • 分页与表服务的工作方式是,当您查询表以获取一些数据时,表服务可以返回的最大实体数为 1000。不能保证总是返回 1000 个实体。根据您的查询方式,它可能小于 1000 甚至 0。但是,如果有更多可用结果,表服务会返回一个名为 Continuation Token 的内容。您必须使用此令牌从表服务中获取下一组结果。有关查询超时和分页的更多信息,请参阅此链接:https://msdn.microsoft.com/en-us/library/azure/dd135718.aspx

    考虑到这两个因素,你不能真正实现用户可以直接跳转到特定页面的分页解决方案(例如,用户坐在第 1 页上,然后用户无法转到第 4 页)。最多可以实现下一页、上一页和首页的功能。

    要实现next page 类型的功能,请存储表服务返回的延续令牌并在查询中使用它。

    要实现previous page 类型的功能,您必须将所有返回的继续标记存储在一个数组或其他东西中,并跟踪用户当前所在的页面(即当前页面索引)。当用户想要转到上一页时,您只需获取上一个索引的延续令牌(即当前页面索引 - 1)并在查询中使用它。

    要实现first page 类型的功能,只需发出不带延续令牌的查询。

    如果您想实现分页,请查看 Storage Client Library 中的 ExecuteQuerySegmented 方法。

    更新

    请参阅下面的示例代码。为了简单起见,我只保留了首页和下一页功能:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.WindowsAzure.Storage.Auth;
    using Microsoft.WindowsAzure.Storage.Blob;
    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Queue;
    using Microsoft.WindowsAzure.Storage.Table;
    namespace TablePaginationSample
    {
        class Program
        {
            static string accountName = "";
            static string accountKey = "";
            static string tableName = "";
            static int maxEntitiesToFetch = 10;
            static TableContinuationToken token = null;
            static void Main(string[] args)
            {
                var cloudStorageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
                var cloudTableClient = cloudStorageAccount.CreateCloudTableClient();
                var table = cloudTableClient.GetTableReference(tableName);
                Console.WriteLine("Press \"N\" to go to next page\nPress \"F\" to go first page\nPress any other key to exit program");
                var query = new TableQuery().Take(maxEntitiesToFetch);
                var continueLoop = true;
                do
                {
                    Console.WriteLine("Fetching entities. Please wait....");
                    Console.WriteLine("-------------------------------------------------------------");
                    var queryResult = table.ExecuteQuerySegmented(query, token);
                    token = queryResult.ContinuationToken;
                    var entities = queryResult.Results;
                    foreach (var entity in entities)
                    {
                        Console.WriteLine(string.Format("PartitionKey = {0}; RowKey = {1}", entity.PartitionKey, entity.RowKey));
                    }
                    Console.WriteLine("-------------------------------------------------------------");
                    if (token == null)//No more token available. We've reached end of table
                    {
                        Console.WriteLine("All entities have been fetched. The program will now terminate.");
                        break;
                    }
                    else
                    {
                        Console.WriteLine("More entities available. Press \"N\" to go to next page or Press \"F\" to go first page or Press any other key to exit program.");
                        Console.WriteLine("-------------------------------------------------------------");
                        var key = Console.ReadKey();
                        switch(key.KeyChar)
                        {
                            case 'N':
                            case 'n':
                                continue;
                            case 'F':
                            case 'f':
                                token = null;
                                continue;
                            default:
                                continueLoop = false;
                                break;
                        }
                    }
                } while (continueLoop);
                Console.WriteLine("Press any key to terminate the application.");
                Console.ReadLine();
            }
        }
    }
    

    【讨论】:

    • 感谢您的回复。我对这个概念相当陌生。你能举个例子给我解释一下吗?
    • 用示例代码更新了我的答案。请看一下。 HTH。
    • 应该注意的是,这个解决方案并不总是像您希望的那样工作。如果查询的执行时间超过 5 秒,您将得到一个小于最大结果的结果和一个延续令牌。我在我的应用程序中实现了类似的解决方案,有时我会得到空白页,我必须多次点击“下一步”才能获得第一个结果。
    • 我意识到这不会给讨论增加任何内容,但这可能是我访问 Stack Overflow 后最沮丧的一次。不过,我很欣赏@GauravMantri 的回答和 Mike 的评论(上图)。
    猜你喜欢
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多