我的要求是做客户端分页。即根据客户给出的值($ top,$ skip)返回一组记录。但根据我的下面的代码,我只能使用filter关键字和top或skip。
[HttpGet]
public PageResult<PersistedUser> GetAllUsers(ODataQueryOptions options)
{
TableServiceContext serviceContext = tableClient.GetDataServiceContext();
serviceContext.IgnoreResourceNotFoundException = true;
CloudTableQuery<PersistedUser> users = serviceContext
.CreateQuery<PersistedUser>(TableNames.User)
.AsTableServiceQuery();
IQueryable<PersistedUser> results = options
.ApplyTo(users.AsQueryable()) as IQueryable<PersistedUser>;
// manipulate results. Add some calculated variables to the collection etc
return new PageResult<PersistedUser>(results, null, 0);
}
我不确定这是否也是正确的做法。但我的基本要求是我有一个巨大的数据库,但我只需要在一个有效的时间内一次返回一小组实体。如果有人能提供一些代码片段,我将非常感激。
答案 0 :(得分:0)
我使用相同的方式,它工作正常。
几乎没有差异:
我有一个服务层,可以揭露我的真实情况。在我的服务中,我返回IQueryable并应用O Data过滤器。
[AuthKey]
[GET("api/brands/")]
public PageResult<BrandViewModel> GetBrands(ODataQueryOptions<Brand> options)
{
var brands = (IQueryable<Brand>)options.ApplyTo(_brandServices.FindBrands());
return new PageResult<BrandViewModel>(BrandViewModel.ToViewModel(brands), Request.GetNextPageLink(), Request.GetInlineCount());
}
答案 1 :(得分:0)
以下是使用通用版ODataQueryOptions
的代码的更新版本,并应用$top
和$skip
选项进行分页。
[HttpGet]
public PageResult<PersistedUser> GetAllUsers(
ODataQueryOptions<PersistedUser> options)
{
TableServiceContext serviceContext = tableClient.GetDataServiceContext();
serviceContext.IgnoreResourceNotFoundException = true;
CloudTableQuery<PersistedUser> users = serviceContext
.CreateQuery<PersistedUser>(TableNames.User)
.AsTableServiceQuery();
IQueryable<PersistedUser> results = options.ApplyTo(users);
int skip = options.Skip == null ? 0 : options.Skip.Value;
int take = options.Top == null ? 25 : options.Top.Value;
return new PageResult<PersistedUser>(
results.Skip(skip).Take(take).ToList(),
Request.GetNextPageLink(),
null);
}
答案 2 :(得分:0)
规划OData模型时,请将其与底层存储模型分开。在某些域中,可能会公开组,然后使用导航属性来访问组的成员。
例如,假设您有预订系统。您可以按日期时间将预订存储在长而长的表格中。
但是你可以通过分组成年和周的集合来暴露OData模型。
http://service.net/odata/year(2013)/week(22)/bookings
在您的控制器中,您可以根据提供的时间参数撰写表存储范围查询。
如果有> 1,000次预订,但数量不多,您可以在服务器端浏览它们,耗尽集合,并将所有预订交还给OData客户端,或者对它们进行排序并允许IQueryable组。见注释,底部。
这将为OData消费者提供一种过滤数据的自然机制,同时保持较低的结果集大小。如果每周有许多预订,则可以按星期和小时进一步细分。
这完全是理论上的,但我认为OData v4及其包含功能将允许路由这些URL并描述关系,以便为像Excel这样的OData消费者生成正确的元数据。
请注意,在上面的示例代码中,他们创建了一个用于计算所包含项目的任意路由/ URL,因此它似乎很灵活。
如果不允许嵌套包含,则可以考虑在OData EDM中使用Year和Week属性的BookingRange实体允许:
http://service.net/odata/bookingrange(2013,22)/bookings
我考虑的另一个想法是在插入时计算页码。也就是说,在TS实体本身上有一个PageNumber,并使用算法为其分配页码。这与生成一个好的分区键基本相同,但是有很多页/分区。
一个预计容纳200米行的表可以有1米的页面(生成一个大的伪随机数并将其修改为1米),每个包含200个项目。首先,大多数页面都是空的,因此您需要编写一个页面映射算法,随着行数的增加而改变。 &#34;页&#34; 1映射到页面范围0000001 - 0000100等
正如您所看到的,这变得越来越复杂,但它本质上与Azure一样,用于跨分区自动平衡数据并在其节点之间传播这些分区。
最终,这将再次需要一种方式来对抗&#34; Page&#34;要在URL中指定的号码。最后,每个页面将包含不同数量的项目,具体取决于所用算法的分布。
注意 - 我认为TS不支持top和skip或skip的原因是返回的行的顺序无法保证并且TS中没有排序机制(这将是是一个很大的负担)。因此,从top和skip整理的页面将包含&#34; random&#34;每次都包。
这意味着我上面提到的对一个子集/数据组进行分页的建议要求在应用top和skip之前将整个子集带入服务层并应用排序顺序,尽管它可能是认为客户应该明白没有订单的顶部/跳过是没有意义的,他们有责任发送正确的选项。