2011-04-01 10 views
5

Estoy trabajando con un servicio de datos WCF apuntando a un punto final OData. Si utilizo DataServiceQuery, puedo administrar la continuación sin ningún problema.¿Cómo se manejan las continuaciones en WCF-OData con una consulta URL?

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); 

Sin embargo, no veo cómo se puede hacer lo mismo para un DataServiceContext.BeginExecute (String 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 
}); 

¿Cómo puedo usar el método de consulta basado en url pero aún así obtener soporte de continuación?

Respuesta

3

Una muestra síncrona (para que sea más simple):

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()); 

En resumen, el método Execute devuelve instancia de QueryOperationResponse, que implementa IEnumerable pero también expone la continuación.

+0

Gracias, que trabajó para mí. – EndangeredMassa

2

Para completar, aquí está la función completa que sigue a continuación para las consultas de 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

Otra aproximación es que ambos métodos devuelven IEnumerable e implementan usando retorno de rendimiento, en lugar de cargar todos los elementos en la lista de titulares. Así que perezoso es mejor cuando el volumen de datos es grande. – Lester

2

Utilice un empadronador perezoso

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

Falta la definición de entidades. –

+0

@Lester: su respuesta es corta y elegante. ¡Voto! –

Cuestiones relacionadas