使用BlobHierarchyItems获取Azure Storage中.bacpac文件列表遇重复项
问题原因分析与修复方案
根本原因
你的方法一出现重复项,大概率是以下两个原因之一:
包含非活跃状态的Blob实例
你调用GetBlobsByHierarchy时传入了BlobStates.All,这个参数会返回目标路径下所有状态的Blob:包括活跃的原Blob、已生成的快照、软删除的版本(如果存储账户开启了软删除或版本控制)。这些不同的Blob实例拥有相同的Name属性,导致你的代码将它们误判为同一个文件重复添加。前缀参数与路径判断逻辑的冗余
你的backupDirectory以/结尾,结合字符串截取的判断方式,可能在某些路径结构下(比如存在嵌套虚拟目录),同一Blob被层级遍历逻辑多次匹配到(虽然这种情况相对少见,但会导致重复)。同时,用Contains("bacpac")判断文件类型不够严谨,可能误匹配路径中包含该字符串的非目标文件。
针对性修复方案
修复点1:只获取活跃状态的Blob
将BlobStates.All替换为BlobStates.Active,排除快照、软删除等非活跃实例,从源头避免重复。
修复点2:优化路径匹配与文件名提取逻辑
用StartsWith精准匹配前缀,EndsWith判断文件后缀,替代字符串截取和模糊匹配;直接通过索引截取文件名,比Replace更可靠。
修复后的完整代码
public static List<string> GetBackupFiles(string dbName) { string backupPrefix = $"{dbName}/dbbackups"; List<string> backupFiles = new(); BlobServiceClient blobServiceClient = GetStorageAccount(_StorageConnectionString); BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(_ActiveProjectsContainer); // 仅获取活跃状态的Blob,排除快照、软删除版本 var blobHierarchyItems = containerClient.GetBlobsByHierarchy( BlobTraits.All, BlobStates.Active, delimiter: "/", prefix: $"{backupPrefix}/"); // 结尾带/确保只匹配该路径下的直接子项 foreach (var hierarchyItem in blobHierarchyItems) { if (hierarchyItem.IsBlob) { BlobItem blob = hierarchyItem.Blob; // 精准匹配前缀和文件后缀 if (blob.Name.StartsWith($"{backupPrefix}/", StringComparison.OrdinalIgnoreCase) && blob.Name.EndsWith(".bacpac", StringComparison.OrdinalIgnoreCase)) { // 提取前缀后的文件名部分 string fileName = blob.Name[(backupPrefix.Length + 1)..]; backupFiles.Add(fileName); } } } return backupFiles; }
额外验证建议
如果修复后仍有重复,可登录Azure Portal检查目标Blob是否存在快照或软删除版本——这些实例在存储中是独立的,但名称与原Blob一致,是导致重复的常见诱因。
内容的提问来源于stack exchange,提问作者E. A. Bagby
相关产品推荐
相关产品推荐

