自定义ITableEntity派生类查询Azure Table Storage时触发空引用异常
使用Azure.Data.Tables自定义ITableEntity派生类查询时抛出ArgumentNullException异常
使用Azure.Data.Tables从Azure Table Storage获取数据时,直接用TableEntity查询遍历一切正常,但改用自定义的ITableEntity派生类TaskInfo时,遍历查询结果的foreach步骤抛出System.ArgumentNullException异常。
代码示例
Pageable<TaskInfo> tasks = tableClient.Query<TaskInfo>(t => t.PartitionKey == "20210325"); Pageable<TableEntity> tasks2 = tableClient.Query<TableEntity>(filter: $"PartitionKey eq '20210325'"); foreach (var task2 in tasks2) { Console.WriteLine($"{task2.GetString("TaskDescription")}"); } Console.WriteLine($"The query returned {tasks2.Count()} entities."); foreach (var task in tasks) { Console.WriteLine(task.TaskDescription); } Console.WriteLine($"The query returned {tasks2.Count()} entities."); public class TaskInfo : ITableEntity { public string? PartitionKey { get; set; } = ""; public string? RowKey { get; set; } = ""; public DateTimeOffset? Timestamp { get; set; } public ETag ETag { get; set; } // 此处省略的属性中包含非可空数值类型(如int/long) }
异常信息
System.ArgumentNullException HResult=0x80004003 Message=Value cannot be null. (Parameter 's') Source=System.Private.CoreLib StackTrace: at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.Int64.Parse(String s, IFormatProvider provider) at Azure.Data.Tables.TablesTypeBinder.TryGet[T](BoundMemberInfo memberInfo, IDictionary`2 source, T& value) at Azure.Core.TypeBinder`1.BoundMemberInfo`1.Deserialize(TExchange source, Object o, TypeBinder`1 binderImplementation) at Azure.Core.TypeBinder`1.BoundTypeInfo.Deserialize[T](TExchange source) at Azure.Data.Tables.DictionaryTableExtensions.ToTableEntity[T](IDictionary`2 entity, BoundTypeInfo typeInfo) at Azure.Data.Tables.DictionaryTableExtensions.ToTableEntityList[T](IReadOnlyList`1 entityList) at Azure.Data.Tables.TableClient.<>c__DisplayClass56_0`1.<Query>b__0(Nullable`1 pageSizeHint) at Azure.Core.PageableHelpers.<>c__DisplayClass12_0`1.<CreateEnumerable>b__0(String _, Nullable`1 pageSizeHint) at Azure.Core.PageableHelpers.FuncPageable`1.<AsPages>d__4.MoveNext() at Azure.Pageable`1.<GetEnumerator>d__8.MoveNext() at AnalyzeImportProcesses.Program.AnalyzeRetailPriceImportProcess() in C:\Users\cward\source\repos\AnalyzeImportProcesses\AnalyzeImportProcesses\Program.cs:line 44 at AnalyzeImportProcesses.Program.Main(String[] args) in C:\Users\cward\source\repos\AnalyzeImportProcesses\AnalyzeImportProcesses\Program.cs:line 23
问题根源
从栈跟踪可以定位到异常核心:在将Table Storage中的字符串值解析为long类型时传入了null参数。这说明TaskInfo类中定义了非可空的数值类型(如int/long)属性,但对应存储中的部分实体里,该字段的值为null或者根本不存在,导致解析时触发ArgumentNullException。
解决方案
- 将
TaskInfo中的数值类型属性改为可空值类型,比如把long TaskId改成long? TaskId,这样当存储中没有对应值时,属性会被赋值为null,不会触发解析异常。 - 如果业务逻辑要求必须使用非可空数值类型,给属性设置默认值,比如
public long TaskId { get; set; } = 0;,确保解析时即使没有对应值也能有默认值填充。 - 检查Azure Table Storage中的目标实体,确保所有对应
TaskInfo数值类型属性的字段都存在且有有效值,不存在null或缺失的情况。
验证步骤
修改TaskInfo类的数值属性为可空类型后,重新运行查询代码,遍历tasks集合时即可正常获取数据,不再抛出异常。
内容的提问来源于stack exchange,提问作者Chris Ward
相关产品推荐
相关产品推荐

