2011-04-01 57 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