Как выполнять запросы IQueryable в MongoDB? - PullRequest
2 голосов
/ 25 мая 2020

Я пытаюсь подключить некую структуру, основанную на интерфейсе IQueryable (например, OData, если вам интересно).

Моя текущая проблема может быть описана с помощью следующего фрагмента:

var queryable = database.GetCollection<MyItems>("myItems").AsQueryable();
var count1 = queryable.Select(x => x.Order.StateInfo).Count();
// var count2 = queryable.Select(x => x.Order).Select(x => x.StateInfo).Count();

Этот код работает, но если вы раскомментируете последнюю строку, вы получите:

System.ArgumentException: Expression of type 'System.Collections.Generic.IEnumerable`1[MyApp.Common.Models.StateInfo]' 
cannot be used for parameter of type 'System.Linq.IQueryable`1[MyApp.Common.Models.StateInfo]' of method
 'Int32 Count[StateInfo](System.Linq.IQueryable`1[MyApp.Common.Models.StateInfo])' (Parameter 'arg0')
   at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)
   at System.Linq.Expressions.Expression.Call(MethodInfo method, Expression arg0)
   at System.Linq.Expressions.MethodCallExpression1.Rewrite(Expression instance, IReadOnlyList`1 args)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at MongoDB.Driver.Linq.Processors.Transformer.Visit(Expression node)
   at MongoDB.Driver.Linq.Processors.Transformer.Transform(Expression node)
   at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Prepare(Expression expression)
   at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Translate(Expression expression)
   at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at MongoDB.Driver.Linq.MongoQueryable.CountAsync[TSource](IMongoQueryable`1 source, CancellationToken cancellationToken)

Кажется, что драйвер пытается выполнить некоторые операции в памяти, отбрасывая все IQueryable, поэтому все последующие вызовы терпят неудачу (например, Select / Where / ...). Запрос с двумя последующими парами Select или Select/Where эффективно отравляется и не может быть использован где-либо. Например:

var queryable = database.GetCollection<MyItems>("myItems").AsQueryable();
var count1 = queryable.Select(x => x.Order).Where(x => x.StateInfo != null).Count(); 
// System.InvalidOperationException: '{document}.StateInfo is not supported.'

Что я могу с этим поделать? Может, я могу где-нибудь об этом сообщить?

1 Ответ

2 голосов
/ 07 июня 2020

MongoDB C# Драйвер лишь частично поддерживает IQueryable, потому что слишком сложно реализовать все случаи с конвейером агрегации MongoDB.

Поэтому я не удивлен, если версия 2.10 не поддерживает Select out из другого Select и Where из Select.

Не могу найти никакой информации об этом в текущей документации, но здесь из v1 do c:

Выбор используется для проецирования нового типа результата из соответствующих документов. Проекция обычно должна быть последней операцией (за некоторыми исключениями, такими как Distinct, Max и Min).

Использование IQueryable ограничено базовыми c описанными методами здесь .
и здесь вы можете найти IQueryable тесты, где я снова не могу найти .Select().Select().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...