C#中从指定格式文件名提取去前导零的核心ID匹配数据库ID
C# 文件名与数据库ID匹配解决方案
一、核心ID提取实现
针对0000138_0.jpeg这类文件名,需要提取去除前导零、下划线前的核心ID,推荐两种可靠实现方式:
方法1:字符串分割处理
适合文件名格式固定(仅一个下划线分隔ID和后缀标识)的场景:
private string ExtractCoreId(string fileName) { // 去除文件后缀,获取纯文件名 string nameWithoutExt = Path.GetFileNameWithoutExtension(fileName); // 按下划线分割,取第一部分(ID段) string idSegment = nameWithoutExt.Split('_')[0]; // 移除前导零,若全零则保留单个0 string coreId = idSegment.TrimStart('0'); return string.IsNullOrEmpty(coreId) ? "0" : coreId; }
方法2:正则表达式匹配
适合文件名格式可能存在变化的场景,匹配更精准:
private string ExtractCoreId(string fileName) { // 匹配开头任意数量前导零+数字段+下划线的结构 var match = Regex.Match(fileName, @"^0*(\d+)_"); return match.Success ? match.Groups[1].Value : string.Empty; }
二、修正原有代码逻辑
原代码存在查询条件错误、路径拼接错误、匹配逻辑缺失等问题,以下是修正后的完整实现:
public void SyncProductImages() { // 加载所有未删除的产品数据 List<Product> dbProducts = Db2Context.Product.Where(a => !a.Deleted).ToList(); // 预加载所有产品-图片映射关系,避免循环内重复查询 var allPictureMappings = Db2Context.Product_Picture_Mapping.ToList(); // 一次性加载目标文件夹所有文件,提升IO效率 DirectoryInfo imageDir = new DirectoryInfo(firstPath); if (!imageDir.Exists) { // 可添加日志或异常处理 return; } FileInfo[] allFiles = imageDir.GetFiles(); // 缓存文件名与核心ID的映射,避免重复计算 Dictionary<string, FileInfo> idFileMap = allFiles.ToDictionary( file => ExtractCoreId(file.Name), file => file, StringComparer.OrdinalIgnoreCase ); foreach (Product pro in dbProducts) { string targetId = pro.Id.ToString(); // 确认当前产品有图片映射 if (!allPictureMappings.Any(m => m.ProductId == pro.Id)) continue; // 从缓存中快速匹配对应文件 if (idFileMap.TryGetValue(targetId, out FileInfo matchedFile)) { // 查找或创建目标数据库的产品记录 TBL_Product targetProduct = Db1Context.TBL_Product .FirstOrDefault(p => p.ID == $"SKU-{pro.Id}") ?? new TBL_Product { ID = $"SKU-{pro.Id}" }; targetProduct.Image = matchedFile.FullName; // 处理新增产品的上下文状态 if (Db1Context.Entry(targetProduct).State == EntityState.Detached) Db1Context.TBL_Product.Add(targetProduct); } } // 批量保存数据库更改,提升性能 Db1Context.SaveChanges(); } // 核心ID提取方法(二选一即可) private string ExtractCoreId(string fileName) { var match = Regex.Match(fileName, @"^0*(\d+)_"); return match.Success ? match.Groups[1].Value : string.Empty; }
关键修正点说明
- 预加载数据:一次性加载所有产品、图片映射和文件,减少循环内的数据库/文件系统IO操作
- 查询条件修正:修复原代码中无效的
PictureId == PictureId、ID == "SKU-"等错误条件 - 路径处理:直接使用
FileInfo.FullName获取完整路径,避免手动拼接导致的错误 - 性能优化:用字典缓存文件名与核心ID的映射,将文件匹配的时间复杂度从O(n²)降为O(n)
- 批量保存:统一提交数据库更改,避免循环内频繁提交的性能损耗
三、额外优化建议
- 如果数据库ID是整数类型,可将提取的
coreId转为整数后再匹配,避免字符串比较的潜在问题 - 添加异常捕获逻辑,处理文件路径不存在、数据库连接失败等异常场景
- 若文件数量极大,可考虑分批次处理,避免内存占用过高
内容的提问来源于stack exchange,提问作者k4mil
相关产品推荐
相关产品推荐

