SQL Server Varbinary图片迁移至Firebase遇上传成功但无文件问题求助
一、当前脚本的核心问题
你的脚本显示成功但无图片上传,根源是这几个硬伤:
未读取Varbinary图片数据
SELECT语句里没包含存储图片的Varbinary字段(假设字段名为Md_FileData),且byte[] fileData = /* Retrieve file data from reader */;是注释状态,等于上传空数据。
修复步骤:- 修改查询语句,加入Varbinary字段:
SELECT Md_ID, Md_FileName, Md_FileType, Md_Extension, Md_Title, Md_Desc, Md_FileData FROM dbo.Media - 读取该字段赋值:
byte[] fileData = (byte[])reader["Md_FileData"];
- 修改查询语句,加入Varbinary字段:
Firebase初始化缺失身份验证
仅传入Bucket名称无法完成上传,Firebase需要服务账号凭据授权。
修复:
从Firebase控制台下载JSON格式的服务账号密钥,初始化时配置凭据:var firebaseStorage = new FirebaseStorage( firebaseStorageBucket, new FirebaseStorageOptions { AuthTokenAsyncFactory = async () => { var credential = GoogleCredential.FromFile("service-account-key.json"); var token = await credential.UnderlyingCredential.GetAccessTokenForRequestAsync(); return token; } } );异常被吞导致“假成功”
UploadFileToFirebase方法内的异常仅打印不冒泡,主程序无法感知单个文件上传失败,直接输出“全部成功”。
修复:要么移除该方法内的catch块,让异常传递到主程序统一处理;要么在catch中记录错误日志,并标记任务失败状态。
二、高效迁移的优化方案
针对1500张图片的迁移场景,这些方法能提升效率与可靠性:
流式读取大字段
给ExecuteReaderAsync加上CommandBehavior.SequentialAccess优化大Varbinary字段的读取,避免内存过载:SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess);读取时用
GetBytes分块读取:long bytesRead = 0; int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; using (MemoryStream ms = new MemoryStream()) { while ((bytesRead = reader.GetBytes(reader.GetOrdinal("Md_FileData"), ms.Position, buffer, 0, bufferSize)) > 0) { ms.Write(buffer, 0, (int)bytesRead); } fileData = ms.ToArray(); }控制并发上传
用SemaphoreSlim限制并发数(比如同时上传5-10个),比串行上传大幅提升速度:var semaphore = new SemaphoreSlim(5); var tasks = new List<Task>(); while (await reader.ReadAsync()) { await semaphore.WaitAsync(); tasks.Add(Task.Run(async () => { try { // 读取数据、调用UploadFileToFirebase逻辑 } finally { semaphore.Release(); } })); } await Task.WhenAll(tasks);断点续传与状态追踪
给SQL的Media表新增IsUploaded(布尔型)、FirebaseUrl(字符串型)字段。每次上传成功后更新这两个字段,失败则标记未上传。后续迁移可只处理未上传的文件,避免重复劳动。同时记录每个文件的上传日志(成功/失败原因),方便排查问题。数据一致性保障
采用“先上传图片,再更新SQL引用”的顺序,确保只有Firebase上传成功时,才把存储路径写入SQL。必要时可使用事务,避免出现“SQL有引用但Firebase无文件”的不一致情况。
内容的提问来源于stack exchange,提问作者Zille e elahi

