Reputation: 10015
I'm trying to connect some framework that is based on IQueryable interface (i.e. OData if you wonder).
My current problem can be described using following snippet:
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();
This code works but if you uncomment the last line you get:
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)
It seems that driver tries to perform some operations in-memory, dropping the whole IQueryable
thing, so all the subsequent calls fail (like Select/Where/...). Query with two subsequent Select
's or Select/Where
pair get efficiently poisoned and cannot be used anywhere. For example:
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.'
What can I do about it? Maybe I can report it somewhere?
Upvotes: 3
Views: 3668
Reputation: 1222
MongoDB C# Driver just partially supports IQueryable
because it's too hard to implement all cases with MongoDB aggregation pipeline.
So I'm not surprised if version 2.10 doesn't support Select
out of another Select
and Where
out of Select
.
Can't find any info about this in current documentation but here from v1 doc:
Select is used to project a new result type from the matching documents. A projection must typically be the last operation (with a few exceptions like Distinct, Max and Min).
Using IQueryable
is limited to basic methods described here.
And here you can find IQueryable
tests, where again I can't find .Select().Select()
.
Upvotes: 1