You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Partition Key删除Cosmos DB项时输入格式错误问题排查

问题描述

尝试使用分区键删除Cosmos DB中的记录时,出现错误:

The input string '1bf23515-ccdc-446d-8b27-d8bdf4494e73' was not in a correct format

在执行GetByIdAsync方法中的idsWithPartitionKeys.Add((idValue, partitionKeyValue));语句时,同样提示ID输入字符串格式不正确。需求是获取带有分区键的ID,完成记录删除操作。

提供的代码

DeleteStudentAsync方法

public async Task<bool> DeleteStudentAsync<T>(string partitionKey)
{
    try
    {
        var studentDetails = await GetByIdAsync<T>(partitionKey);
        foreach (var document in studentDetails)
        {
            if (document.partitionKeyValue != null)
            {
                PartitionKey partitionKeyValue = new PartitionKey(document.partitionKeyValue.ToString());
                await _container.DeleteItemAsync<dynamic>(document.id, partitionKeyValue);
            }
        }
    
        return true;
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
}

GetByIdAsync方法

public async Task<List<(string id, TPartitionKey partitionKeyValue)>> GetByIdAsync<TPartitionKey>(
string partitionKey)
{
    try
    {
        var sqlQueryText = new QueryDefinition($"SELECT c.StudentId, c.{partitionKey} FROM c");
        var idsWithPartitionKeys = new List<(string id, TPartitionKey partitionKeyValue)>();

        using var resultSetIterator = _container.GetItemQueryIterator<dynamic>(sqlQueryText);
    
        while (resultSetIterator.HasMoreResults)
        {
            var response = await resultSetIterator.ReadNextAsync();
            foreach (var document in response)
            {
                var partitionKeyValue = (TPartitionKey)document[partitionKey];
                idsWithPartitionKeys.Add((idValue, partitionKeyValue));
            }
        }
    
        return idsWithPartitionKeys;
    }
    catch (Exception a)
    {
        Console.WriteLine(a);
        throw;
    }

}

Cosmos DB数据示例

Cosmos DB数据示例截图

解决方案

问题根源

  1. GetByIdAsync方法中未定义idValue变量,直接使用导致引用错误,进而触发格式异常
  2. 直接强制转换分区键值为泛型类型TPartitionKey,容易因类型不匹配抛出转换错误

修正后的代码

GetByIdAsync方法

public async Task<List<(string id, TPartitionKey partitionKeyValue)>> GetByIdAsync<TPartitionKey>(string partitionKey)
{
    try
    {
        var sqlQueryText = new QueryDefinition($"SELECT c.StudentId, c.{partitionKey} FROM c");
        var idsWithPartitionKeys = new List<(string id, TPartitionKey partitionKeyValue)>();

        using var resultSetIterator = _container.GetItemQueryIterator<dynamic>(sqlQueryText);
    
        while (resultSetIterator.HasMoreResults)
        {
            var response = await resultSetIterator.ReadNextAsync();
            foreach (var document in response)
            {
                // 从查询结果中获取StudentId并转为字符串
                var idValue = document.StudentId.ToString();
                // 安全转换分区键值到目标类型
                var partitionKeyRawValue = document[partitionKey];
                TPartitionKey partitionKeyValue;
                try
                {
                    partitionKeyValue = (TPartitionKey)Convert.ChangeType(partitionKeyRawValue, typeof(TPartitionKey));
                }
                catch (InvalidCastException)
                {
                    throw new InvalidOperationException($"无法将分区键值 {partitionKeyRawValue} 转换为类型 {typeof(TPartitionKey)}");
                }
                idsWithPartitionKeys.Add((idValue, partitionKeyValue));
            }
        }
    
        return idsWithPartitionKeys;
    }
    catch (Exception a)
    {
        Console.WriteLine(a);
        throw;
    }
}

DeleteStudentAsync方法

public async Task<bool> DeleteStudentAsync<TPartitionKey>(string partitionKeyFieldName)
{
    try
    {
        var studentDetails = await GetByIdAsync<TPartitionKey>(partitionKeyFieldName);
        foreach (var document in studentDetails)
        {
            PartitionKey partitionKeyValue = new PartitionKey(document.partitionKeyValue.ToString());
            await _container.DeleteItemAsync<dynamic>(document.id, partitionKeyValue);
        }
    
        return true;
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
}

关键修复点

  • 补充idValue变量的赋值逻辑,从查询结果中正确获取StudentId,解决ID未定义的问题
  • 使用Convert.ChangeType替代直接强制转换,更安全地处理分区键的类型转换,避免类型不匹配报错
  • 明确DeleteStudentAsync的泛型参数为分区键类型,保证与GetByIdAsync的类型一致

内容的提问来源于stack exchange,提问作者Syedfahad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 01:00:19