2010-06-22 7 views
11

j'ai couru avec succès la déclaration suivante à la Northwind.sdf dans LINQPad:Existe-t-il une méthode générale pour vérifier si une propriété est définie par un fournisseur Linq, en particulier OData?

from s in Shippers 
    select new 
{ 
    s.ShipperID, 
    s.CompanyName,  
    Count=s.ShipViaOrders.Count()  
} 

En même temps, je ne ai pas exécuter une instruction similaire avec le Service OData (http://services.odata.org/northwind/northwind.svc) dans LINQPad:

from s in Shippers  
select new 
{ 
    s.ShipperID, 
    s.CompanyName,  
    Count=s.Orders.Count()  
} 

l'erreur est "Construire ou l'initialisation des instances du type <> f__AnonymousType0`3 [System.Int32, System.String, System.Int32] avec l'expression s.Orders.Count() ne sera pas supporté.".

Je sais que le service OData est très limité dans Linq Support. J'ai un support de déclaration Linq dynamique dans mon application. En fait, j'essaie de migrer la source de données de Compact SQL Server vers le service OData.

Donc je dois traiter avec NotSupportedException d'une manière générale. À l'heure actuelle, j'essaie de vérifier la syntaxe de la propriété définir avant de l'exécuter, comme

"s.Orders.Count() as Count" 

Il a passé mon chèque, mais il rencontré NotSupportedException de OData.

Existe-t-il un moyen de vérifier si une propriété définie (par une chaîne ou un lambda) est prise en charge par un fournisseur Linq?

Toutes les suggestions sont appréciées.

Ying

Répondre

6

Malheureusement, il n'y a aucun moyen de programmation générale de vérifier si un fournisseur LINQ sera capable de traduire une requête donnée. Typiquement, vous devrez recourir à la documentation ou (bien sûr) réellement essayer les requêtes comme vous le faites.

fournisseurs différents peuvent toutefois fournir un mécanisme de générer une certaine représentation de la requête, que vous pourrez peut-être utiliser pour vérifier si la requête fonctionnerait sans avoir à l'exécuter.

Dans le cas du client OData, vous pouvez invoquer .ToString() sur la requête, et il doit renvoyer une URL si elle est en mesure de traiter avec succès la requête; sinon, il retournera un message d'erreur semblable à 'Erreur de traduction de l'expression Linq en URI: ...' (le message d'erreur réel peut changer en fonction de la langue de l'utilisateur, mais il ne sera certainement pas un URI valide).

+0

@Ying: Cela ressemble à * la * réponse à moi. Si oui, vous pouvez l'accepter. – chiccodoro

2

Malheureusement, la seule façon de le savoir est en testant une requête spécifique ou au moyen de documents si le créateur du fournisseur LINQ a fourni une liste détaillée de ce qui est pas pris en charge.

LINQ lui-même a une spécification très lâche largement définie par les méthodes d'extension définies sur IQueryable/IEnumerable. L'implémentation d'un fournisseur LINQ signifie que vous devez implémenter une traduction sur la source de données, par ex. LINQ to SQL traduit l'arbre d'expression exprimé dans une requête LINQ en SQL qui est compris par un fournisseur de base de données. Chaque source de données a ses propres limites qui régiront finalement ce qui peut être supporté, et de même chaque fournisseur LINQ peut choisir de mettre en œuvre (ou de ne pas implémenter) une méthode ou un comportement particulier.

Il se peut que ce soit juste une limitation du fournisseur dans LINQPad pour traiter OData - vous pouvez vouloir vérifier OQuery à la place et voir si cela fournit un meilleur ensemble de capacités pour vous - jetez un oeil à http://beta.code.msdn.microsoft.com/OQuery-Building-OData-d2e75eed pour les détails et un téléchargement.