Cosmos DB SQL API NOT IN 运算符采用 List WithParameter(Listt) 不起作用

sqlserver

1个回答

写回答

666778

2025-08-19 13:10

+ 关注

AI
AI

解决 Cosmos DB SQL API NOT IN 运算符采用 List WithParameter(List) 不起作用

在使用 Azure Cosmos DB SQL API 进行数据查询时,我们经常会遇到需要使用 NOT IN 运算符的情况。NOT IN 运算符可以用于排除某个特定的值或一组值。然而,有时我们可能会发现使用 List WithParameter(List) 方法传递参数给 NOT IN 运算符时,出现了一些问题,导致查询结果不正确。本文将探讨这个问题的原因,并提供解决方案。

问题背景

在使用 Cosmos DB SQL API 进行数据查询时,我们可以使用 SQL 语句来筛选出符合特定条件的文档。例如,我们可以使用 WHERE 子句来限定查询结果的范围。而在 WHERE 子句中,我们可以使用 NOT IN 运算符来排除某些特定的值。

通常情况下,我们可以使用 List WithParameter(List) 方法将一个列表参数传递给 SQL 查询。这个方法可以帮助我们简化代码,提高可读性,并且防止 SQL 注入攻击。

然而,当我们尝试将一个列表参数传递给 NOT IN 运算符时,可能会遇到一些问题。这些问题可能导致查询结果不正确,甚至无法正常工作。

问题原因

问题的根本原因在于 Cosmos DB SQL API 在处理 NOT IN 运算符时,对于列表参数的处理方式与我们预期的不一致。具体来说,Cosmos DB SQL API 并不会将列表参数直接映射到 SQL 查询中的 NOT IN 运算符。

相反,Cosmos DB SQL API 会将列表参数解析为一个数组,并使用 ARRAY_CONTAINS_ANY 函数来处理 NOT IN 运算符。这意味着,当我们使用 List WithParameter(List) 方法传递参数给 NOT IN 运算符时,实际上是将参数传递给了 ARRAY_CONTAINS_ANY 函数。

ARRAY_CONTAINS_ANY 函数接受两个参数:一个数组和一个要匹配的值。它将返回一个布尔值,指示数组中是否存在与要匹配的值相等的元素。因此,当我们使用 List WithParameter(List) 方法传递参数给 NOT IN 运算符时,实际上是在尝试查找数组中与要排除的值相等的元素,而不是排除这些值。

解决方案

要解决这个问题,我们需要找到一种方法来正确使用 NOT IN 运算符,并将列表参数传递给它。一种可行的解决方案是使用自定义函数来模拟 NOT IN 运算符的行为。

我们可以创建一个自定义函数,它接受一个数组和一个要排除的值作为参数,并返回一个布尔值。在函数内部,我们可以使用 ARRAY_CONTAINS_ANY 函数来判断数组中是否存在与要排除的值相等的元素。如果存在,则返回 false,否则返回 true。

下面是一个示例代码,演示了如何使用自定义函数来模拟 NOT IN 运算符的行为:

csharp

using Microsoft.Azure.Cosmos;

public static class CosmosDBQueryHelper

{

public static SqlQuerySpec GenerateNotInQuerySpec<T>(string propertyName, List<T> valuesToExclude)

{

string query = $"SELECT * FROM c WHERE NOT udf.IsInArray(c.{propertyName}, @valuesToExclude)";

SqlParameterCollection parameters = new SqlParameterCollection();

parameters.Add(new SqlParameter("@valuesToExclude", valuesToExclude));

return new SqlQuerySpec(query, parameters);

}

public static bool IsInArray<T>(T value, IEnumerable<T> array)

{

return array.ContAIns(value);

}

}

public class Document

{

public string Id { get; set; }

public string Name { get; set; }

}

public async Task<List<Document>> QueryDocumentsExcludingValues(List<string> valuesToExclude)

{

List<Document> results = new List<Document>();

using (CosmosClient client = new CosmosClient("connectionString"))

{

Database Database = awAIt client.GetDatabase("DatabaseId");

ContAIner contAIner = awAIt Database.GetcontAIner("contAInerId");

SqlQuerySpec querySpec = CosmosDBQueryHelper.GenerateNotInQuerySpec("Name", valuesToExclude);

FeedIterator<Document> iterator = contAIner.GetItemQueryIterator<Document>(querySpec);

while (iterator.HasMoreResults)

{

FeedResponse<Document> response = awAIt iterator.ReadNextAsync();

results.AddRange(response);

}

}

return results;

}

在上面的示例代码中,我们创建了一个名为 CosmosDBQueryHelper 的辅助类,其中包含了一个生成查询规范的方法 GenerateNotInQuerySpec 和一个自定义函数 IsInArray。通过调用 GenerateNotInQuerySpec 方法,我们可以生成一个查询规范,该规范将使用自定义函数来模拟 NOT IN 运算符的行为。然后,我们可以使用生成的查询规范来执行查询,并获取结果。

在使用 Cosmos DB SQL API 进行数据查询时,如果遇到 NOT IN 运算符无法正确处理列表参数的问题,我们可以使用自定义函数来模拟 NOT IN 运算符的行为。通过这种方式,我们可以正确地使用 NOT IN 运算符,并将列表参数传递给它。希望本文提供的解决方案能够帮助您解决这个问题,并顺利进行 Cosmos DB 数据查询。

举报有用(4分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号