2016-07-05 5 views
3

J'essaie d'exécuter une requête LINQ sur une collection Azure DocumentDB. Quand je lance ma requête, je continue à obtenir un AggregateException qui contient un InvalidOperationException avec le message:"L'objet nullable doit avoir une valeur" quand Où utilise une méthode?

objet Nullable doit avoir une valeur

J'ai réduit cette question à ce qui suit (un peu artificiel) par exemple :

Quand je lance ce code, je reçois l'exception mentionnée ci-dessus jeté de l'appel à ToArray()

public class MyDocument { ... } 

public void RunQuery() 
{ 
    var query = documentDbClient 
     .CreateDocumentQuery<MyDocument>() 
     .Where(doc => GetDoc(doc) != null); 
    var results = query.ToArray() 
} 

public MyDocument GetDoc(MyDocument myDocument) 
{ 
    return myDocument; 
} 

En revanche, lorsque je lance le code ci-dessous aucune exception n'est levée et je récupère de bons résultats de la collection DocumentDB.

public void RunQuery() 
{ 
    var query = documentDbClient 
     .CreateDocumentQuery<MyDocument>() 
     .Where(doc => doc != null); 
    var results = query.ToArray() 
} 

Pourquoi la différence de comportement entre les deux exemples de code?

Notes:
- Alors que GetDoc() est une position dans ma logique sous-jacente plus complexe, le code reproduit ci-dessus la question exactement. Je ne retiens pas de manigances à l'intérieur GetDoc() ou d'autres méthodes :)
- Le problème se produit même lorsque GetDoc() est faite static.
- Juste essayé de reproduire avec un List<MyDocument> au lieu de documentDbClient et aucune exception n'a été levée. Indique quelque chose dans le fournisseur de données sous-jacent = Azure DocumentDB IDatabaseClient.

+1

Eh bien, alors votre méthode 'GetDoc' est le problème :). Donc soit vous montrez la méthode, soit nous ne pouvons pas vous aider. – ckruczek

+1

La méthode GetDoc renvoie apparemment un type non nullable. –

+0

Je ne sais pas Azure DocumentDB. Donc, ce n'est peut-être pas une réponse appropriée. Mais avec Entity Framework, ce code va faire une erreur lors de l'exécution car il ne peut pas rappeler BACK dans le code du côté appelant (par exemple votre fonction GetDoc). Je peux voir n'importe quel système comme celui-ci ayant ce type de problème. Peut-être qu'il prend en charge un délégué? par exemple.Func whereClause = (d) => {return d; } "où vous pouvez au moins envelopper votre logique complexe dans un Func réutilisable –

Répondre

5

Avec l'aide de @ andrew-liu et @will je suis en mesure de comprendre que (merci!):

Au moment de l'appel à Where() dans mon exemple ci-dessus, le prédicat est interprété à l'intérieur (plutôt que exécuté) en tant qu'expression LINQ. Au moment de l'appel à ToArray() l'expression LINQ est exécutée par rapport au fournisseur LINQ DocumentDB .NET SDK.

Parce que le SDK est pas au courant de ma méthode GetDoc(), il jette l'exception avec le message cryptique « objet Nullable doit avoir une valeur ».

Dans v1.9 du DocumentDB SDK pour .Net, le message d'erreur est beaucoup plus clair. Un DocumentQueryException est lancé avec un message comme "Méthode" GetDoc() "n'est pas pris en charge".

Vous pouvez obtenir des commentaires similaires à partir de la version 1.8 du SDK en appelant ToString() sur la requête comme suit: query.ToString().