如何在条件判断中使用Azure表检索行属性及实现行增改逻辑
实现Azure表的条件Upsert(创建/补全属性)与属性检查
看起来你已经在着手处理Azure表的行操作了,我来帮你把这两个需求落地——先是完善行属性的非空检查,再实现「不存在则创建,存在则补全缺失属性」的逻辑。
一、完善行检查与属性非空验证
你的rowExists函数可以扩展一下,不仅判断行是否存在,还能顺便检查目标属性是否非空。这里假设你有对应的实体类(如果不想定义实体类,后面也会提供动态实体的写法):
public class LocationEntity : TableEntity { public LocationEntity(string state, string city) { PartitionKey = state; RowKey = city; } public LocationEntity() { } // Azure SDK反序列化需要无参构造函数 public double? Latitude { get; set; } public double? Longitude { get; set; } public string City { get; set; } public string State { get; set; } }
基于实体类的属性检查
把rowExists改成更语义化的函数,同时返回行存在状态和属性完整性:
public static async Task<(bool exists, bool hasAllRequiredProperties)> CheckLocationEntity(CloudTable table, string city, string state) { var retrieveOp = TableOperation.Retrieve<LocationEntity>(state, city); var result = await table.ExecuteAsync(retrieveOp); if (result.Result == null) { // 行不存在 return (exists: false, hasAllRequiredProperties: false); } var entity = result.Result as LocationEntity; // 逐一检查目标属性是否非空/有有效值 var hasAllProps = entity.Latitude.HasValue && entity.Longitude.HasValue && !string.IsNullOrEmpty(entity.City) && !string.IsNullOrEmpty(entity.State); return (exists: true, hasAllRequiredProperties: hasAllProps); }
基于动态实体的属性检查(无需定义实体类)
如果不想提前定义实体类,可以用DynamicTableEntity来处理:
public static async Task<(bool exists, bool hasAllRequiredProperties)> CheckDynamicLocationEntity(CloudTable table, string city, string state) { var retrieveOp = TableOperation.Retrieve(state, city); var result = await table.ExecuteAsync(retrieveOp); if (result.Result == null) { return (exists: false, hasAllRequiredProperties: false); } var entity = result.Result as DynamicTableEntity; // 检查属性是否存在且有有效值 var hasLatitude = entity.Properties.ContainsKey("Latitude") && entity.Properties["Latitude"].DoubleValue.HasValue; var hasLongitude = entity.Properties.ContainsKey("Longitude") && entity.Properties["Longitude"].DoubleValue.HasValue; var hasCity = entity.Properties.ContainsKey("City") && !string.IsNullOrEmpty(entity.Properties["City"].StringValue); var hasState = entity.Properties.ContainsKey("State") && !string.IsNullOrEmpty(entity.Properties["State"].StringValue); return (exists: true, hasAllRequiredProperties: hasLatitude && hasLongitude && hasCity && hasState); }
二、实现「不存在则创建,存在则补全缺失属性」的逻辑
Azure Table Storage的TableOperation.InsertOrMerge正好匹配你的需求:
- 若行不存在:直接创建新行
- 若行存在:仅更新你提供的非空属性,保留原有行的其他属性
带前置检查的Upsert逻辑
如果需要先判断属性状态再执行操作,可以这样写:
public static async Task UpsertLocationEntity(CloudTable table, string city, string state, double? latitude = null, double? longitude = null) { var (exists, hasAllProps) = await CheckLocationEntity(table, city, state); if (!exists) { // 行不存在,创建完整实体(确保必填属性有值) var newEntity = new LocationEntity(state, city) { Latitude = latitude ?? throw new ArgumentNullException(nameof(latitude)), Longitude = longitude ?? throw new ArgumentNullException(nameof(longitude)), City = city, State = state }; await table.ExecuteAsync(TableOperation.Insert(newEntity)); } else if (!hasAllProps) { // 行存在但属性不全,用Merge补全缺失属性 var updateEntity = new LocationEntity(state, city); // 只设置需要补全的非空属性 if (latitude.HasValue) updateEntity.Latitude = latitude; if (longitude.HasValue) updateEntity.Longitude = longitude; if (!string.IsNullOrEmpty(city)) updateEntity.City = city; if (!string.IsNullOrEmpty(state)) updateEntity.State = state; await table.ExecuteAsync(TableOperation.Merge(updateEntity)); } // 行存在且属性完整时,无需操作 }
简洁版自动Upsert
如果不需要复杂的前置判断,直接用InsertOrMerge就能自动处理创建/合并逻辑:
public static async Task UpsertLocationWithMerge(CloudTable table, LocationEntity entity) { var upsertOp = TableOperation.InsertOrMerge(entity); await table.ExecuteAsync(upsertOp); }
三、在条件判断中使用检索到的行属性
比如你想根据现有行的Latitude是否为空,决定是否更新它:
public static async Task UpdateLatitudeIfMissing(CloudTable table, string city, string state, double newLatitude) { var retrieveOp = TableOperation.Retrieve<LocationEntity>(state, city); var result = await table.ExecuteAsync(retrieveOp); if (result.Result == null) { // 行不存在,直接创建带Latitude的新行 var newEntity = new LocationEntity(state, city) { Latitude = newLatitude }; await table.ExecuteAsync(TableOperation.Insert(newEntity)); return; } var entity = result.Result as LocationEntity; if (!entity.Latitude.HasValue) { // Latitude为空,执行更新 entity.Latitude = newLatitude; await table.ExecuteAsync(TableOperation.Merge(entity)); } }
你可以按照这个思路,基于检索到的行属性做任意自定义条件判断,再执行对应的操作。
内容的提问来源于stack exchange,提问作者Andrew Buikema
相关产品推荐
相关产品推荐

