这个答案实际上是对您对 Ladislav Mrnka 的最后评论的回答。你说:
好的,我明白了,所以不可能有“免费甜甜圈”。在 LINQ to Any 中,我们有这样的行为,但有必要跨越服务边界,即要(反)序列化的数据会破坏它,对吗?
虽然它不是免费的,但它仍然是可能的!
在服务器端,您必须提供一个初始化请求的方法和一个获取结果的方法,一个一个。
在客户端——特别是在它的一个低级基础设施类中——您可以将它包装在一个枚举器中,最后,您的“业务”类可以像使用其他枚举器一样使用该枚举器。
我们已经讨论过,它将在每个项目所需的请求-响应方式中引入额外的开销。这将引入延迟并增加网络负载。
使用伪 RESTful API 的这种方法的示例可能如下所示:
服务器端:
POST http://server/api/search-specification
:
正文包含搜索所需的参数,例如开始日期和结束日期
。响应将是标识搜索规范的 URI。
GET http://server/api/search-specification/1/next-result
:
响应将是下一个项目。
这个控制器看起来像这样:
public Response PostSearchSpecification(SearchSpecification spec)
{
int id = _searches.Max(x => x.Key) + 1; // Make thread-safe
_searches[id] = _provider.GetSome().GetEnumerator();
return ...;
}
public Item GetNextResult(int searchSpecId)
{
if(_searches[searchSpecId].MoveNext())
return _searches.Current;
else
return null; // or return a HTTP status code that tells the
// client that there are no more items.
}
我称它为伪 RESTful API,因为它看起来确实像一个,但它需要在内部保持每个规范的状态以启用延迟执行。另外GET http://server/api/search-specification/1/next-result
不是幂等的。
但我认为它证明了我的意思:)
客户端会像这样封装它:
class Search
{
public IEnumerable<Item> Start(params)
{
var client = new HttpClient(...);
var resultsUri = client.Post(new SearchSpecification(params)).Response;
Item item = client.Get<Item>(resultsUri);
while(item != null)
{
yield return item;
item = client.Get<Item>(resultsUri);
}
}
}
你会像这样使用它:
var search = new Search();
foreach(var item in search.Start(...))
// ...
只是一个关于如何实现这样的东西的原始草图。