添加分页 MVC 和 Azure table 存储
Add Pagination MVC and Azure table storage
我正在尝试将分页应用于我的 MVC 应用程序。我正在使用 Azure table 存储
这是我尝试过的:-
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 个条目。现在如何显示和实现 "Previous" 和 "Next" 以在下一页显示其余条目?如何实现控制器和 HTML 页面的其余部分?
感谢任何帮助。
关于分页,有几点需要考虑:
- Table 服务不支持所有 LINQ 运算符(以及 OData 查询选项)。例如
Skip
不受支持。有关支持的运算符列表,请参阅此 link:https://msdn.microsoft.com/en-us/library/azure/dd135725.aspx.
- 分页与 Table 服务一起工作的方式是,当您查询 table 以获取一些数据时,table 服务可以返回的最大实体数是 1000。无法保证始终返回 1000 个实体。根据您的查询方式,它可能小于 1000 甚至 0。但是,如果有更多可用结果,Table 服务 returns 称为
Continuation Token
的东西。您必须使用此令牌从 table 服务获取下一组结果。有关查询超时和分页的更多信息,请参阅此 link:https://msdn.microsoft.com/en-us/library/azure/dd135718.aspx。
考虑到这两个因素,您无法真正实现用户可以直接跳转到特定页面的分页解决方案(例如,用户坐在第 1 页,然后用户无法转到第 4 页)。您最多可以实现下一页、上一页和第一页这类功能。
要实现 next page
类功能,请存储 table 服务返回的延续令牌并在您的查询中使用它。
要实现 previous page
类功能,您必须将返回的所有继续标记存储在数组或其他内容中,并跟踪用户当前所在的页面(即当前页面索引)。当用户想要转到上一页时,您只需获取上一个索引的延续标记(即当前页面索引 - 1)并在查询中使用它。
要实现 first page
种功能,只需发出不带继续标记的查询。
如果要实现分页,请查看存储客户端库中的 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();
}
}
}
我正在尝试将分页应用于我的 MVC 应用程序。我正在使用 Azure table 存储
这是我尝试过的:-
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 个条目。现在如何显示和实现 "Previous" 和 "Next" 以在下一页显示其余条目?如何实现控制器和 HTML 页面的其余部分?
感谢任何帮助。
关于分页,有几点需要考虑:
- Table 服务不支持所有 LINQ 运算符(以及 OData 查询选项)。例如
Skip
不受支持。有关支持的运算符列表,请参阅此 link:https://msdn.microsoft.com/en-us/library/azure/dd135725.aspx. - 分页与 Table 服务一起工作的方式是,当您查询 table 以获取一些数据时,table 服务可以返回的最大实体数是 1000。无法保证始终返回 1000 个实体。根据您的查询方式,它可能小于 1000 甚至 0。但是,如果有更多可用结果,Table 服务 returns 称为
Continuation Token
的东西。您必须使用此令牌从 table 服务获取下一组结果。有关查询超时和分页的更多信息,请参阅此 link:https://msdn.microsoft.com/en-us/library/azure/dd135718.aspx。
考虑到这两个因素,您无法真正实现用户可以直接跳转到特定页面的分页解决方案(例如,用户坐在第 1 页,然后用户无法转到第 4 页)。您最多可以实现下一页、上一页和第一页这类功能。
要实现 next page
类功能,请存储 table 服务返回的延续令牌并在您的查询中使用它。
要实现 previous page
类功能,您必须将返回的所有继续标记存储在数组或其他内容中,并跟踪用户当前所在的页面(即当前页面索引)。当用户想要转到上一页时,您只需获取上一个索引的延续标记(即当前页面索引 - 1)并在查询中使用它。
要实现 first page
种功能,只需发出不带继续标记的查询。
如果要实现分页,请查看存储客户端库中的 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();
}
}
}