web-dev-qa-db-fra.com

Filtre OData $ avec des éléments dans un $ expand

J'ai donné quelques services Web pour accéder aux informations.

La première chose que j'ai essaye de développer un nœud. Et je l'ai fait avec succès avec le code suivant

http://www.domain.com/ODataService/WorkService.svc/CaseStudies?format=json&$expand=ServiceOfferings

Maintenant, je veux filtrer ServiceOfferingID que j'obtiendrai lors de l'expansion de ServiceOfferings. Comment peut utiliser l'option de filtre sur une collection étendue

http://www.domain.com/ODataService/WorkService.svc/CaseStudies?format=json&$expand=ServiceOfferings&$filter=ServiceOfferings.ServiceOfferingID eq 127 

Mais ça ne marche pas. Quelle est la bonne façon de faire de même

25
Null Pointer

La requête que vous devrez écrire dépend de la cardinalité de la collection étendue.

Voici quelques exemples qui utilisent le public exemple de service OData Northwind, fourni par odata.org .

Une commande est toujours effectuée par exactement un client.

Recherchez les commandes passées par un client avec un nom spécifique: http://services.odata.org/V3/Northwind/Northwind.svc/Orders?$expand=Customer&$filter=Customer/CompanyName eq 'Vins et alcools Chevalier ' . Cela équivaut à la réponse de Dhawal.

Un client peut émettre de nombreuses commandes.

Utilisez les quantificateurs all ou any to précisez si vous voulez qu'au moins une ou toutes les commandes respectent vos conditions.

  1. Recherchez les clients pour lesquels une ou plusieurs commandes ont été traitées par un employé spécifique: http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/ tout (o: o/EmployeeID eq 9)
  2. Trouvez des clients qui n'ont rien commandé depuis longtemps: http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/ tous (o: o/OrderDate lt DateTime'1997-01-01 ')

Vous pouvez appeler http://services.odata.org/V3/Northwind/Northwind.svc/$metadata et inspecter les éléments NavigationProperty pour voir quelles relations existent.

<NavigationProperty Name="Orders" 
    Relationship="NorthwindModel.FK_Orders_Customers" 
    ToRole="Orders" 
    FromRole="Customers"/>

Ensuite, recherchez une association avec ce nom et vous trouverez la cardinalité:

<Association Name="FK_Orders_Customers">
    <End 
         Type="NorthwindModel.Customer" 
         Role="Customers" 
         Multiplicity="0..1"/>
    <End 
         Type="NorthwindModel.Order" 
         Role="Orders" 
         Multiplicity="*"/>
    ...

Navigation dans une relation un-à-plusieurs comme celle-ci: http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/EmployeeID eq 9 , vous donnera: "La valeur parente pour l'accès à la propriété d'une propriété 'EmployeeID' n'est pas une valeur unique. L'accès à la propriété ne peut être appliqué qu'à une seule valeur."

Naviguer dans une relation plusieurs-à-un avec tout ou partie, comme http://services.odata.org/V3/Northwind/Northwind.svc/Orders?$expand=Customer&$filter=Customer/any (c : c/CompanyName eq 'Vins et alcools Chevalier') , vous donnera: "Tout/Tout ne peut être utilisé qu'après une collecte."

Soit dit en passant, all() et any() sont en fait Quantificateur universel , ∀ () et quantificateur existentiel , ∃ () , respectivement, dont vous vous souviendrez peut-être en cours de mathématiques.

41
R. Schreurs

Le filtrage par les propriétés de l'objet enfant est pris en charge dans oData.

Voici un exemple: http://services.odata.org/Northwind/Northwind.svc/Orders?$filter=Customer/Country eq 'Germany'

9
Dhawal

Dans OData, la commande Filtre ne fonctionne que sur l'élément de niveau supérieur. Pour que votre filtre fonctionne, vous devez disposer de l'URL suivante

http://www.example.com/ODataService/WorkService.svc/CaseStudies(x)/ServiceOfferings?format=json&$filter=ServiceOfferingID eq 127

Évidemment, ce n'est pas la requête que vous essayez d'écrire, mais en arrière-plan, votre requête est convertie en une arborescence d'expression qui a une expression racine basée sur l'élément de niveau supérieur.

Si vous aviez vraiment besoin de filtrer les données, vous pourriez potentiellement intercepter la requête et écrire votre propre expression comme ci-dessous:

[QueryInterceptor("CaseStudies")]
public Expression<Func<CaseStudie, bool>> CaseStudieFilter()
{
    <Expression here>
}
6
SCB

Vous pouvez également y parvenir via un webget sur le service. J'ai dû faire quelque chose de similaire pour filtrer par propriétés des propriétés.

0
George