我们要将52000个文件(.pdf
,.xls
,.doc
...等)导入SQL Server 2012数据库。
我有一个包含文件名称的Dossier_fichier.txt
文件。我将这些名称加载到一个集合中,然后循环遍历此集合,我尝试在direcotry PiecesJointes
中找到这些文件并将它们转换为字节并使用以下代码将它们插入数据库:
var dossierFichiers = addOrUpdateHelper.ReadEntities<DossierFichier, DossierFichierMap>("dossier_fichier.txt").ToArray();
// (2) Parcourir toutes les instances de DossierFichier chargées + Lire le fichier référencé + Le charger dans la propriété Fichier
var dirPath = System.IO.Path.Combine(Environment.CurrentDirectory, "piecesJointes");
var nbfichier = 0;
foreach (var df in dossierFichiers) {
try {
var path = System.IO.Path.Combine(dirPath, string.Concat( df.Code,"_", df.Nom));
df.Fichier = File.ReadAllBytes(path);
context.DossierFichier.Add(df);
context.SaveChanges();
Logger.Info("Le fichier {0} a été inséré", df.Nom);
nbfichier++;
} catch (FileNotFoundException ex) {
Logger.Error("Fichier {0} : {1}", df.Nom, ex.Message);
} catch (Exception ex) {
Logger.Error("Fichier {0} : {1}",df.Nom, ex.Message);
}
}
插入4000个文件后我得到OutOFMemoryException
,花了很多时间(60个小时)。请问你能帮助我插入所有这些文件而不是OutOfmemoryException
,以及如何更快地完成它?
答案 0 :(得分:5)
看起来您的代码具有O(n 2 )性能,因为它将所有文件内容保存在内存中。
您应该能够通过将更新“批处理”来解决这个问题:
context.SaveChanges();
context.SaveChanges();
,然后将context
替换为新实例。这将确保所有对象只保存一次,数据库往返次数受到控制,并且内存中永远不会有超过100个对象。
此外,您可以通过将文件内容粘贴到df.Fichier
来保留文件内容。这可能会使您的系统内存不足,因此您应该复制df
:
var path = System.IO.Path.Combine(dirPath, string.Concat( df.Code,"_", df.Nom));
var dfCopy = new DossierFichier(df); // Copy df's fields
dfCopy.Fichier = File.ReadAllBytes(path);
context.DossierFichier.Add(dfCopy);
答案 1 :(得分:1)
对于集合中的每个项目,将整个文件内容(字节数组)添加到df.Fichier
。这是内存使用量增加的原因之一。
您可以使用临时变量解决此特定问题。