2011-04-01 54 views
5

我正在使用指向OData端点的WCF数据服务。如果我使用DataServiceQuery,则可以毫无困难地管理延续。如何使用URL查询处理WCF-OData中的延续?

var collection = new DataServiceCollection<T>(); 
collection.LoadCompleted += (sender, e) => 
    { 
     if (e.Error != null) 
     { 
      callback(null, e.Error); 
      return; 
     } 

     var thisCollection = (DataServiceCollection<T>) sender; 
     if (thisCollection.Continuation != null) 
     { 
      thisCollection.LoadNextPartialSetAsync(); 
     } 
     else 
     { 
      var items = thisCollection.ToList(); 
      callback(items, e.Error); 
     } 
    }; 
collection.LoadAsync(query); 

不过,我看不出你如何能为DataServiceContext.BeginExecute做同样的(字符串的URL,...)方法。

_odataContext.BeginExecute<T>(new Uri(requestUrl), x => 
{ 
    var items = _odataContext.EndExecute<T>(x); 

    //not sure how to get the rest of the items with this method 
}); 

如何使用基于url的查询方法,但仍然得到延续支持?

回答

3

的同步样本(使其更简单):

var r = ctx.Execute<Product>(new Uri("http://services.odata.org/Northwind/Northwind.svc/Products")); 
QueryOperationResponse<Product> response = (QueryOperationResponse<Product>)r; 
response.Count(); 
Console.WriteLine(response.GetContinuation()); 

总之,Execute方法返回QueryOperationResponse,其实现IEnumerable的实例,但也暴露了延续。

+0

谢谢你,为我工作。 – EndangeredMassa 2011-04-01 21:11:02

2

为了完整起见,下面是完整的功能,它遵循URL查询的延续。

public void ExecuteFullQuery<T>(Uri requestUrl, Action<IEnumerable<T>> callback) 
{ 
    var list = new List<T>(); 
    ExecuteFullQueryImpl(requestUrl, list, callback); 
} 

private void ExecuteFullQueryImpl<T>(Uri requestUrl, List<T> items, Action<IEnumerable<T>> callback) 
{ 
    _odataContext.BeginExecute<T>(requestUrl, x => 
    { 
     var results = _odataContext.EndExecute<T>(x); 
     if (results != null) 
      items.AddRange(results.ToList()); 

     var response = (QueryOperationResponse<T>)results; 
     var continuation = response.GetContinuation(); 
     if (continuation != null) 
     { 
      ExecuteFullQueryImpl(continuation.NextLinkUri, items, callback); 
     } 
     else 
     { 
      callback(items); 
     } 
    }, 
    null); 
} 
+0

另一种方法是这两种方法都返回IEnumerable 并使用yield return来实现,而不是将所有元素加载到持有者列表中。当数据量很大时,懒惰更好。 – Lester 2013-12-02 16:24:08

2

使用一个懒惰的枚举

public IEnumerable<Product> GetProducts() 
{ 
    Uri request = new Uri("http://services.odata.org/Northwind/Northwind.svc/Products"); 

    var response = (QueryOperationResponse<Product>)ctx.Execute<Product>(request); 

    while (true) 
    { 
     foreach (Product p in response) 
     { 
      yield return p; 
     } 

     var continuation = response.GetContinuation(); 
     if (continuation == null) 
     { 
      yield break; 
     } 

     response = ctx.Execute(continuation); 
    } 
} 
+0

您错过了实体的定义。 – 2014-04-03 17:47:33

+0

@Lester:你的回答简短而优雅。 Upvote! – 2015-09-27 14:16:50