【问题标题】:How do I perform IQueryable requests in MongoDB?如何在 MongoDB 中执行 IQueryable 请求?
【发布时间】:2020-09-12 09:53:37
【问题描述】:

我正在尝试连接一些基于 IQueryable 接口的框架(即 OData,如果您想知道的话)。

我目前的问题可以用下面的 sn-p 来描述:

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

我能做些什么呢?也许我可以在某个地方报告?

【问题讨论】:

  • GetCollection&lt;MyItems&gt; 返回什么?是IQueryable&lt;MyItems&gt;吗?那你为什么要使用AsQueraybel()MyItemOrder 是否在单独的表中? MyItemsOrders 之间有什么关系?如果它在单独的表中,如果您自己进行连接,它是否有效?
  • 没有表格,这是一个mongo文档。这是我使用的 API:mongodb.github.io/mongo-csharp-driver/2.5/apidocs/html/…
  • 好的,现在我明白了。 GetCollection 是一种返回对 Mongo 中一个表的访问权限的方法。 GetCollection&lt;MyType&gt; 返回对包含 MyType 记录行的表的访问。 AsQueryable() 不是 IEnumerable 的扩展方法,而是 MongoCollection 的扩展方法。您可以访问 MyItems 表。 Orders 是 MyItems 的一部分,还是 MyItem 有零个或多个 Orders?在数据库方面:Orders 和 MyItems 之间是否存在一对多(或者可能是多对多)关系?
  • 也许你误解了文档数据库的概念:那里没有任何关系或任何东西。文档是一个整体存储的,你可以把它想象成在磁盘上的.json文件中序列化JSON数组。您可以访问任何条目并获得整个对象树,您没有连接、表格和其他东西。唯一的区别是 mongo 执行查询的速度比使用原始 JSON 文件实现的要快。

标签: c# mongodb linq mongodb-query iqueryable


【解决方案1】:

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

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

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

Select 用于从匹配的文档中投影一个新的结果类型。投影通常必须是最后一个操作(除了 Distinct、Max 和 Min 等少数例外)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    • 2018-06-02
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2023-04-02
    相关资源
    最近更新 更多