#c# #.net #linq #azure-cosmosdb #iqueryable
#c# #.net #linq #azure-cosmosdb #iqueryable
Вопрос:
Я использую Microsoft.Azure.Документы.Интерфейс IDocumentClient для доступа к документам CosmosDB с использованием метода CreateDocumentQuery.
Когда я запускаю код без включения каких-либо запросов linq, я без проблем получаю все свои документы:
client.CreateDocumentQuery<MyDatabaseClass>(CollectionUri, options)
.ToList()
Я хочу получить идентификатор документов, поэтому я пробую следующий код:
client.CreateDocumentQuery<MyDatabaseClass>(CollectionUri, options)
.Select(doc => doc.Id)
.ToList()
И это возвращает 0 результатов.
Если я переключу его и перечислю IQueryable перед выполнением запроса, он работает нормально, но, насколько я понимаю этот материал (хотя есть большая вероятность, что я этого не делаю), это менее эффективно.
client.CreateDocumentQuery<MyDatabaseClass>(CollectionUri, options)
.ToList()
.Select(doc => doc.Id)
Кто-нибудь знает, что я делаю неправильно с запрашиваемым, чтобы это произошло? (Обратите внимание, приведенное выше является упрощенной версией того, чего я на самом деле пытаюсь достичь, но проблема все еще возникает даже на этом уровне).
Схема элемента базы данных:
{
"type": "",
"view": {
"date": "",
"paths": {}
},
"id": "",
"viewId": ""
"version": "",
"_rid": "",
"_self": "",
"_etag": "",
"_attachments": "",
"_ts": ""
}
Класс:
public string Id{ get; private set; }
public string ViewId { get; private set; }
public string Version { get; private set; }
public abstract string Type { get; }
Комментарии:
1. Я не знаю эту базу данных, но запросы linqs не могут преобразовать все запросы на язык базы данных. В SQL Server обычно отображаются предупреждения типа «преобразовать запрос не удалось». И код генерирует несколько запросов SQL для выполнения одного запроса Linq (вероятно, неэффективно). Итак, я полагаю, что эта проблема возникает в вашем случае. Он не может фильтровать на языке вашей базы данных. Но если вы используете ToList (), в котором все данные загружаются в память, возможна фильтрация. Но неэффективно. Попробуйте прочитать документацию db, чтобы убедиться в проблеме.
2. Очевидно, что существует проблема с оценкой запроса на стороне сервера. Можете ли вы предоставить свой реальный запрос и некоторые примеры объектов базы данных, которые связаны с ним?
3. @Paulo, я использую CosmosDB amp; IDocumentClient, которые, как описано здесь, должны иметь возможность использовать LINQ. Однако есть параметры SQL, поэтому я попробую. learn.microsoft.com/en-us/dotnet/api /…
4. @Plusce, простая инструкция select выше — это реальный запрос, который не будет работать. Элементы базы данных выглядят следующим образом:
{ "type": "", "view": { "date": "", "paths": { } }, "id": "", "version": "", "_rid": "", "_self": "", "_etag": "", "_attachments": "", "_ts": }
5. Пожалуйста, отредактируйте свой вопрос и добавьте элемент базы данных, правильно отформатированный к вашему вопросу. Не могли бы вы также указать нам,
IQueryable<...>
что возвращает CreateDocumentQuery<MyDatabaseClass>(…)?
Ответ №1:
Если вы специально не привязаны к LINQ для построения запросов, рассмотрите возможность использования QueryDefinition
класса в .NET SDK для определения ваших запросов в синтаксисе SQL для запуска в Cosmos. В идеале любая фильтрация или формирование выполняются запросом, а не в коде для результата.
Смотрите этот пример для хорошей отправной точки. Только для выбора идентификатора:
QueryDefinition query = new QueryDefinition("select c.id from c");
// Provide query to container.GetItemQueryIterator<MyDatabaseClass>()
Ответ №2:
Я смог обойти эту проблему, используя перегрузку CreateDocumentQuery, которая принимает SQL-запрос вместо использования LINQ.