如何在 cosmos 中通过 QueryDefinition 使用参数化 IN 语句?

问题描述 投票:0回答:2

我有一个查询,当我创建为字符串时该查询有效,但是当我使用

QueryDefinition
并将其作为参数传递时,
IN
子句不起作用。

如何解决这个问题?

这里,

allStockNumbers
将是
"11", "22"
filters?.LineItemState
将是
"someString"

工作:

 var allStockNumbers = string.Join(", ", stockNumbers.Select(x => "\"" + x + "\""));
 var query = !string.IsNullOrWhiteSpace(filters?.LineItemState)
    ? $"SELECT f.id, f.location, f.stockNumber, f.vin, f.totalCarliCost, f.totalCostSubmitted, f.createdDateTime, f.createdBy, f.earliestPaymentDate, f.paymentItems, ARRAY(SELECT * FROM c IN f.lineItems where c.itemState = {"\"" + filters.LineItemState + "\"" }) as lineItems FROM f WHERE f.stockNumber IN ({allStockNumbers})"
    : $"SELECT f.id, f.location, f.stockNumber, f.vin, f.totalCarliCost, f.totalCostSubmitted, f.createdDateTime, f.createdBy, f.earliestPaymentDate, f.paymentItems, f.lineItems FROM f WHERE f.stockNumber IN ({allStockNumbers})";

不工作:

var allStockNumbers = string.Join(", ", stockNumbers.Select(x => "\"" + x + "\""));
QueryDefinition query;
if (!string.IsNullOrWhiteSpace(filters?.LineItemState))
{
    var lineItemState = "\"" + filters.LineItemState + "\"";
    query = new QueryDefinition(
            @"SELECT f.id, f.location, f.stockNumber, f.vin, f.totalCarliCost, f.totalCostSubmitted, f.createdDateTime, f.createdBy, f.earliestPaymentDate, f.paymentItems, ARRAY(SELECT * FROM c IN f.lineItems where c.itemState = @lineItemState) as lineItems FROM f WHERE f.stockNumber IN (@allStockNumbers)"
        ).WithParameter("@lineItemState", @lineItemState)
        .WithParameter("@allStockNumbers", allStockNumbers);
}
else
{
    query = new QueryDefinition(
        @"SELECT f.id, f.location, f.stockNumber, f.vin, f.totalCarliCost, f.totalCostSubmitted, f.createdDateTime, f.createdBy, f.earliestPaymentDate, f.paymentItems, f.lineItems FROM f WHERE f.stockNumber IN (@allStockNumbers)"
    ).WithParameter("@allStockNumbers", allStockNumbers);
}

我也尝试过

ARRAY_CONTAINS
但同样的事情:

var allStockNumbers = string.Join(", ", stockNumbers.Select(x => "\"" + x + "\""));
QueryDefinition query;
if (!string.IsNullOrWhiteSpace(filters?.LineItemState))
{
     var lineItemState = "\"" + filters.LineItemState + "\"";
     query = new QueryDefinition(
              "SELECT f.id, f.location, f.stockNumber, f.vin, f.totalCarliCost, f.totalCostSubmitted, f.createdDateTime, f.createdBy, f.earliestPaymentDate, f.paymentItems, ARRAY(SELECT * FROM c IN f.lineItems where c.itemState = @lineItemState) as lineItems FROM f WHERE ARRAY_CONTAINS(@allStockNumbers, f.stockNumber)"
          ).WithParameter("@lineItemState", lineItemState)
          .WithParameter("@allStockNumbers", allStockNumbers);
}
else
{
    query = new QueryDefinition(
        @"SELECT f.id, f.location, f.stockNumber, f.vin, f.totalCarliCost, f.totalCostSubmitted, f.createdDateTime, f.createdBy, f.earliestPaymentDate, f.paymentItems, f.lineItems FROM f WHERE f.stockNumber IN (@allStockNumbers)"
    ).WithParameter("@allStockNumbers", allStockNumbers);
}
c# azure-cosmosdb azure-cosmosdb-sqlapi asp.net-core-6.0
2个回答
0
投票

我已将

IN
QueryDefinition
对象一起使用,如下面的代码片段所示。

以下是我为获得所需输出而遵循的步骤:

  • 第一个 For 循环在迭代 id 数组时将查询参数添加到查询定义对象。

  • 然后使用提要迭代器,我们以分页的方式获取结果集对象。 hasmoreresult 集属性确保检索继续进行,直到有任何符合条件的记录可用为止。

  • Cosmos DB 查询的结果集是通过使用 while 循环进行迭代的。 resultSet 对象是一个 FeedIterator,可以对查询结果进行分页检索。

  • 我所做的更改是将输入转换为 Json 并将输入与 LINQ 一起使用,而在您的情况下,直接使用 LINQ 查询。

以下是代码片段:

    public static async Task Main(string[] args)
    {
        try
        {
            using (CosmosClient cosmosClient = new CosmosClient(endpointUrl, authKey))
            {
            
            // Getting the CosmosDB container and database name to retrieve records.
                Database database = cosmosClient.GetDatabase(databaseName);

                
                Container container = database.GetContainer(containerName);

                
                string[] ids = { "guid1", "guid2", "guid3" };

                // Query text with parameterized query
                string queryText = "SELECT * FROM c WHERE c.Id IN ({0})";
                string parameterName = "@ids";
                string[] parameterValues = ids.Select((id, index) => $"{parameterName}{index}").ToArray();
                string parameterizedQuery = string.Format(queryText, string.Join(",", parameterValues));

                // Create a QueryDefinition object with the parameterized query
                QueryDefinition query = new QueryDefinition(parameterizedQuery);

                for (int i = 0; i < ids.Length; i++)
                {
                    query = query.WithParameter($"{parameterName}{i}", ids[i]);
                }

                // List to store queried employees
                List<Employee> employees = new List<Employee>();

                using (FeedIterator<Employee> resultSet = container.GetItemQueryIterator<Employee>(query))
                {
                    while (resultSet.HasMoreResults)
                    {
                        FeedResponse<Employee> response = await resultSet.ReadNextAsync();
                        employees.AddRange(response);
                    }
                }

                foreach (Employee employee in employees)
                {
                    Console.WriteLine($"Id: {employee.Id}, StockNumber: {employee.StockNumber}");

                    
                    Employee newEmployee = new Employee
                    {
                        Id = Guid.NewGuid().ToString(),
                        StockNumber = employee.StockNumber
                    };

                    // Writing into CosmosDB item(optional)
                    ItemResponse<Employee> response = await container.CreateItemAsync(newEmployee);
                    Employee savedEmployee = response.Resource;

                    Console.WriteLine($"Saved document with Id: {savedEmployee.Id}");
                }
            }
        }
        catch (CosmosException ex)
        {
            Console.WriteLine($"CosmosException while querying documents: StatusCode={ex.StatusCode}, SubStatusCode={ex.SubStatusCode}, Message={ex.Message}, ActivityId={ex.ActivityId}");
        }

        Console.WriteLine("Press Enter to exit.");
        Console.ReadLine();
    }
}
  • 以下是期望的结果: enter image description here

  • 我在控制台中得到的结果也可以保存在 CosmosDb 项目中的 Json 文件中,如下截图所示: enter image description here


0
投票

可能这个问题不再相关,但这就是我所做的。

allStockNumbers =  $"'{string.Join("','", stockNumbers)}'"

我认为它应该完成这项工作。

LinqPad Sample

© www.soinside.com 2019 - 2024. All rights reserved.