【发布时间】:2015-05-16 05:50:54
【问题描述】:
我正在使用 ASP.NET Web API 创建一个 RESTful API。 一个典型的控制器使用 LINQ to objects 从我的存储库中请求实体。我的存储库没有使用实体框架,也没有访问任何数据库。相反,它使用外部 RESTFul 服务进行数据访问。 控制器使用 Skip() 和 Take() 实现分页。
我想了解的部分是调用外部Web服务时将Skip()和Take()转换为请求参数是否有意义。换句话说:我很想知道是否可以使用 LINQ 的 Skip() 和 Take() 对外部 Web 服务的调用应用分页,而不是对包含所有对象的结果 IEnumerable 应用分页。
这是从我自己的存储库中检索数据的典型 LINQ 语句。
var userRoles = from userRole in Repository.UserRole.Load()
.Skip(10)
.Take (10)
select ModelFactory.Create(userRole);
我的存储库将像这样从外部 Web 服务请求数据:
protected override IEnumerable<UserRole> LoadAll()
{
//....
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(GetUrl());
string parameters =
String.Format("?sessionkey={0}&take={1}&skip={2}", take, skip, Session);
HttpResponseMessage response = client.GetAsync(parameters).Result;
//....skipped. deseralize response using JsonConvert and return IEnumerable<UserRole>
}
使用 LINQ 查询并将其转换为 Web 请求的 take 和 skip 参数是否可行且合理,或者我应该将普通的旧 skip 和 take 整数参数传递给 LoadAll() 方法?
【问题讨论】:
-
最好将 Take 和 Skip 传递给远程服务,从而避免下载所有记录然后只获取其中的一部分。
-
同意,绝对将分页参数传递给远程服务是最好的。不过,我的问题是,如何在 LoadAll() 方法中找出取值和跳过的值。我可以以某种方式从 LINQ 查询中获取它们吗?如果没有,那么我将传入参数而不是使用 LINQ 进行 Take 和 Skip。但是,这意味着在我的控制器中我使用 LINQ 进行分页(或不使用),因为我必须知道我的存储库如何进行分页。这对我来说似乎不干净。
-
这里是
Load()LoadAll()的另一个名字吗?您的第一个代码 sn-p 是否调用了您的第二个代码 sn-p 中的方法? -
我很抱歉没有解释这一点。 LoadAll() 将由 Load() 调用。 Load() 是公共接口,LoadAll() 是受保护的。
-
@DavidHartmann,恕我直言,@JLRische 的答案就是您要找的。考虑到远程服务可以直接访问数据,Reposity 类应该非常努力地将过滤参数传递给远程服务(Where、Take、Skip 等)。也就是说,客户端过滤应该是例外,而不是规则。最后,远程服务应该使用更通用的名称来抽象参数,例如
page、pageSize,以及将使用 Where() 表达式应用的其他参数。