使用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数据示例

解决方案
问题根源
GetByIdAsync方法中未定义idValue变量,直接使用导致引用错误,进而触发格式异常- 直接强制转换分区键值为泛型类型
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
相关产品推荐
相关产品推荐

