2016-07-05 12 views
3

Я пытаюсь запустить запрос LINQ для коллекции Azure DocumentDB. Когда я запускаю мой запрос я получаю сообщение AggregateException, который содержит InvalidOperationException с сообщением:«Нулевой объект должен иметь значение», когда Где используется метод?

Nullable объект должен иметь значение

Я уменьшил этот вопрос к следующему (несколько надуманному), например :

Когда я запускаю этот код, я получаю выше исключение выброшен из вызова 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; 
} 

Напротив, когда я запускаю код ниже, исключение не генерируется, и я получаю хорошие результаты из коллекции DocumentDB.

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

Почему разница в поведении между двумя образцами кода?

Примечание:
- В то время как GetDoc() является стендом в моей более сложной логике предикатов, код выше воспроизводит этот вопрос точно. Я не отказываюсь от каких-либо махинаций внутри GetDoc() или другими способами :)
- Проблема возникает, даже когда GetDoc() сделан static.
- Просто попытался воспроизвести с List<MyDocument> вместо documentDbClient и никаких исключений не было. Обозначает что-то в базовом поставщике данных = Azure DocumentDB's IDatabaseClient.

+1

Ну, тогда ваш метод GetDoc - это проблема :). Поэтому либо вы показываете метод, либо мы не можем вам помочь. – ckruczek

+1

Метод GetDoc, по-видимому, возвращает тип с нулевым значением. –

+0

Я не знаю, Azure DocumentDB. Таким образом, это не может быть подходящим ответом. Но с Entity Framework этот код будет выходить из строя во время выполнения, потому что он не может вызвать BACK в код на вызывающей стороне (например, функцию GetDoc). Я вижу такую ​​систему, которая имеет такой тип проблемы. Возможно, он поддерживает делегата? напримерFunc whereClause = (d) => {return d; }, где вы можете по крайней мере обернуть свою сложную логику в многократно используемом Func. –

ответ

5

С помощью @ андрей-Liu и @will я был в состоянии понять, что (спасибо!):

В момент вызова Where() в моем примере выше, предикат внутри интерпретируется (а не выполняться) как выражение LINQ. Во время вызова ToArray() выражение LINQ выполняется против провайдера LINQ DocumentDB .NET SDK.

Поскольку SDK не знает мой GetDoc() метода, он бросает исключение с загадочным сообщением «Nullable объектом должен иметь значение».

В v1.9 SDK DocumentDB для .Net сообщение об ошибке намного яснее. A DocumentQueryException выбрасывается с сообщением вроде «Метод« GetDoc() »не поддерживается».

Вы можете получить похожие отзывы от v1.8 SDK, вызвав ToString() по следующему запросу: query.ToString().

Смежные вопросы