我正在使用CosmosDB以及加载过滤数据的内容。我想在数据库端进行过滤,但我遇到了一些问题,我想我设法解决了这些问题,但不确定为什么一种方法有效,而另一种方法无效。
我有一个CarPositions 的列表
// I fill this list from cosmosdb data
var carPosition = new List<CarPositions>()
我的目标是只有当我在汽车位置列表中有他们的位置时才能得到汽车
我试着做一些类似的事情
var iterator = CarContainer
.GetItemLinqQueryable<Car>(true)
.Where(x => carPosition.Any(cp => cp.Id == x.Id))
.ToFeedIterator();
它抛出了一个异常"输入不是IDocumentQuery"类型;
从我在网上看到的情况来看,CosmosDb提供商在将查询转换为SQL 时不支持ANY linq
这让我尝试做同样的事情,但使用选择和包含
1(
var iterator = CarContainer
.GetItemLinqQueryable<Car>(true)
.Where(x => carPosition.Select(cp => cp.Id).ToList().Contain(x.Id))
.ToFeedIterator();
再次导致相同的异常
然后我尝试了这个方法,但对我来说,这是在做完全相同的事情
2(
var carPosIds = carPosition.Select(cp => cp.Id).ToList();
var iterator = CarContainer
.GetItemLinqQueryable<Car>(true)
.Where(x => carPosIds.Contain(x.Id))
.ToFeedIterator();
有人能解释为什么第二个有效而第一个无效吗?还有为什么Any linq不起作用?
因为linq语句需要转换为将在数据库服务器上运行的sql查询。支持Where
语句中的Contains
语句,因为SDK已经使用sqlIN子句实现了翻译(大概是这样(。
虽然Any
查询看起来是一样的,但想象一下它是一个不同的表达式,以及随着表达式变得越来越复杂,将其转换为SQL查询会变得多么困难(或几乎不可能(。例如.Any(cp => cp.Id * 2 - x.Id / 2 == x.Id)
。
如果这是在内存中运行的纯C#代码,而不是由SDK转换为Cosmos的查询,那么上述所有方法都可以工作(有些方法比其他方法更好(。