1 回答
TA贡献1852条经验 获得超1个赞
所以在这种情况下,我确实认为你想要 IQueryable
而不是IEnumerable
. 最容易记住的方法是将IEnumerable
所有数据加载到内存中,然后运行其余的 LINQ 查询,同时IQueryable
尝试在源上运行过滤器(如果它可以将结果数据加载到内存中)。您确实需要使用支持IQueryable
LINQ to SQL 或 Entity Framework 的 ORM。对于 CosmosDB,SDK 构建在 LINQ to SQL 之上。
通过使用你将所有IEnumerable
数据从 Cosmos加载到内存中,然后应用你的过滤器和分页。当您只有几条记录时这很好,但是随着数据集的增长,您可能可以想象这会如何成为一个主要问题。通常,您希望在数据库中做尽可能多的工作,并且只返回最少数量的结果。这将远远超过使用反射构建谓词的任何性能考虑因素。
的最好的部分之一IQueryable
是它继承自IEnumerable
,因此任何与之一起工作的东西都IEnumerable
将与IQueryable
. 您需要做的就是摆脱您的AsEnumerable()
.
重要的是要注意,并非所有 LINQ 运算符都自动支持,一旦系统遇到无法翻译的运算符,它就会执行目前已有的操作,并在内存中完成其余操作。文档中有CosmosDB 的可用运算符列表。
对于您的查询,最重要的是,虽然您的Where()
条款得到支持,Skip()
但Take()
目前不支持。这意味着每次执行此方法时,所有结果都将从 CosmosDB 返回,然后对分页进行评估。
有几种方法可以在 SDK 中处理分页。当前支持的方式是将MaxItemCount
inside your设置FeedOptions
为您的页面大小。Skip()
当前系统使用延续令牌代替函数。为了访问令牌,您可以使用AsDocumentQuery()
. 由于您必须逐页浏览到下一页,因此缓存令牌可能非常有帮助——跳来跳去很困难。
第二种选择是使用 .Net SDK v3。它目前处于预览阶段,但可在 Nuget 上使用。几个月前启用了 skip/take。在这种情况下,在您调用之前的所有内容ToList()
都应转换为 SQL 并在 CosmosDB 中进行评估。
- 1 回答
- 0 关注
- 118 浏览
添加回答
举报