如何在 MongoDB 中执行 IQueryable 请求?

How do I perform IQueryable requests in MongoDB?

我正在尝试连接一些基于 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/...)。带有两个后续 SelectSelect/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.'

我该怎么办?也许我可以在某处举报?

MongoDB C# 驱动程序仅部分支持 IQueryable,因为使用 MongoDB 聚合管道很难实现所有情况。

因此,如果 2.10 版不支持另一个 Select 中的 SelectSelect 中的 Where,我并不感到惊讶。

在当前文档中找不到关于此的任何信息,但来自 v1 文档:

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).

使用 IQueryable 仅限于描述的基本方法 here
here 你可以找到 IQueryable 测试,我又找不到 .Select().Select().