ASP.NET Core 2.0查询Azure表遇Unexpected EDM type异常求助
这个问题我之前在做Azure Table相关开发时也碰到过,踩过类似的坑!根源在于你的Python脚本写入了空的Double字段,而ASP.NET Core的Azure Table客户端默认的类型解析逻辑没办法处理非可空double类型的null值——当Table服务返回标记为Edm.Double但实际值为空的字段时,客户端就会抛出你看到的这个异常。下面给你几个可行的解决方案,从快速修复到根源解决都有:
double?) 这是最直接省心的方法,因为可空值类型天生就能兼容null值。
假设你原来的实体类是这样的:
public class SensorDataEntity : TableEntity { public double Rating { get; set; } public double Temperature { get; set; } }
只需要把double改成double?即可:
public class SensorDataEntity : TableEntity { public double? Rating { get; set; } public double? Temperature { get; set; } }
修改后,客户端在解析空的Double字段时会自动赋值为null,不会再抛出异常。后续业务逻辑里,你可以通过Rating.HasValue或者Temperature.HasValue来判断是否有有效值,再做对应的处理。
如果业务上要求字段必须是不可空的double类型,那可以自定义一个属性转换器,把空值转换成你需要的默认值(比如0.0)。
首先创建转换器类:
public class DoubleNullConverter : EntityPropertyConverter<double> { // 从Table服务读取数据时的转换逻辑 public override double ConvertBack(EntityProperty property) { // 如果字段为空,返回默认值0.0,你也可以改成其他值 return property?.DoubleValue ?? 0.0; } // 向Table服务写入数据时的转换逻辑 public override EntityProperty Convert(double value) { return EntityProperty.CreateDouble(value); } }
然后在实体类的属性上标记使用这个转换器:
public class SensorDataEntity : TableEntity { [EntityPropertyConverter(typeof(DoubleNullConverter))] public double Rating { get; set; } [EntityPropertyConverter(typeof(DoubleNullConverter))] public double Temperature { get; set; } }
这样读取到空的Double字段时,会自动转换成你设置的默认值,完美规避异常。
如果你的业务逻辑不需要包含空值的记录,那可以在查询阶段就把这些条目排除掉,从根源上避免读取到有问题的字段。
如果你的实体字段已经改成可空类型,查询代码可以这样写:
var tableClient = new TableClient("YourConnectionString", "YourTableName"); var query = tableClient.QueryAsync<SensorDataEntity>( e => e.PartitionKey == "TargetPartitionKey" && e.Rating != null && e.Temperature != null); await foreach (var entity in query) { // 处理正常的实体数据 }
如果还是用非可空的double字段,那可以直接用OData过滤字符串来查询:
var tableClient = new TableClient("YourConnectionString", "YourTableName"); var filter = $"PartitionKey eq 'TargetPartitionKey' and Rating ne null and Temperature ne null"; var query = tableClient.QueryAsync<SensorDataEntity>(filter: filter); await foreach (var entity in query) { // 处理正常的实体数据 }
这样Table服务只会返回符合条件的记录,不会把带空Double字段的条目返回给客户端。
上面的方法都是客户端的修复方案,最彻底的还是从源头解决——修改你的Python脚本,避免写入空的Double字段。
比如用Python的azure-data-tables库写入时,可以在写入前检查值,空值的话要么移除该字段(Azure Table会自动忽略不存在的字段,客户端读取时会用类型默认值),要么设置一个合理的默认值:
# 假设data是准备写入的实体字典 if data.get('rating') is None: # 要么删除空值字段 del data['rating'] # 要么设置默认值 # data['rating'] = 0.0 if data.get('temperature') is None: del data['temperature'] # data['temperature'] = 0.0 # 执行写入操作 table_client.create_entity(entity=data)
这样就不会再产生带空Double字段的记录,后续查询也不会有异常了。
内容的提问来源于stack exchange,提问作者Rik

