Why does a method used in LINQ Where() throw an exception?

12 views
Skip to first unread message

Uri Goldstein

unread,
Jul 5, 2016, 10:21:19 AM7/5/16
to altnetisrael
Hi,

Maybe someone can explain this to me?

When I run this code, I get good results:

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

When I run this code, I get an InvalidOperationException (wrapped in an AggregateException) that says "Nullable object must have a value":

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

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

Seems like calling the method from within the Where() clause is the principal difference here - But why?

Cross-posted from StackOverflow: http://stackoverflow.com/questions/38203734/nullable-object-must-have-a-value-when-where-uses-a-method

Any help would be much appreciated.


Best,
Uri

PS - Doesn't seem crucial but documentDbClient is an Azure DocumentDB IDocumentClient instance.

Avishay Lavie

unread,
Jul 5, 2016, 12:10:21 PM7/5/16
to altnetisrael

If the azure db provider thingy builds an IQueryable, then testing for null is probably translated to something handled at the server, whereas using your own method either forces client execution or worse, exposes a bug in the LINQ provider.

Can you give the stack frame / line the NRE is coming from?


--
You received this message because you are subscribed to the Google Groups "altnetisrael" group.
To unsubscribe from this group and stop receiving emails from it, send an email to altnetisrael...@googlegroups.com.
To post to this group, send email to altnet...@googlegroups.com.
Visit this group at https://groups.google.com/group/altnetisrael.
For more options, visit https://groups.google.com/d/optout.

Ken Egozi

unread,
Jul 5, 2016, 3:47:54 PM7/5/16
to altnet...@googlegroups.com
I am willing to bet that Avishay is 100% correct.

This looks like a linq-provider implementation that is not coded defensively. It expects a property-get expression, and if it gets something else it should in theory provide a pointer about correct usage. 

The provider might be open source, so a PR could be sent out with that.

Ken Egozi

unread,
Jul 5, 2016, 3:48:55 PM7/5/16
to altnet...@googlegroups.com

Uri Goldstein

unread,
Jul 7, 2016, 5:39:25 AM7/7/16
to altnetisrael
Avishay, Ken - Many thanks.

Andrew Liu who I believe is in charge of the DocumentDB .Net SDK has commented in SO that the issue is indeed with their Linq Provider that is unaware of my method at the time of execution.

He also shared that the cryptic error message is a result of sub-optimal error handling inside the SDK and that their upcoming v1.9 will provide a more meaningful error message.

There's a positive side to this - The limitation on not including method calls in the Where lambda has pushed me to better frame my predicate so I've rewritten it a bit more "functionally-oriented" and it's working quite well.


Thanks again!
Uri
Reply all
Reply to author
Forward
0 new messages