ADO.NET +大量插入+ Excel + C#=“不好的时间”?

基本上我需要插入一堆数据到Excel文件。 创build一个OleDB连接似乎是最快的方式,但我已经遇到了内存问题。 进程使用的内存似乎不断增长,因为我执行INSERT查询。 我已经缩小到只有当我输出到Excel文件(内存保持稳定,没有输出到Excel)时发生。 我closures并重新打开每个工作表之间的连接,但这似乎没有影响内存使用情况(如同Dispose())。 数据写入成功,因为我可以validation相对较小的数据集。 如果有人有洞察力,将不胜感激。

initializeADOConn()在构造函数中被调用

initADOConnInsertComm()创build插入参数化插入查询

writeRecord()每当写入新的logging时被调用。 新的工作表是根据需要创build的。

public bool initializeADOConn() { /* Set up the connection string and connect.*/ string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + this.destination + ";Extended Properties=\"Excel 8.0;HDR=YES;\""; //DbProviderFactory factory = //DbProviderFactories.GetFactory("System.Data.OleDb"); conn = new OleDbConnection(connectionString); conn.ConnectionString = connectionString; conn.Open(); /* Intialize the insert command. */ initADOConnInsertComm(); return true; } public override bool writeRecord(FileListerFileInfo file) { /* If all available sheets are full, make a new one. */ if (numWritten % EXCEL_MAX_ROWS == 0) { conn.Close(); conn.Open(); createNextSheet(); } /* Count this record as written. */ numWritten++; /* Get all of the properties of the FileListerFileInfo record and add * them to the parameters of the insert query. */ PropertyInfo[] properties = typeof(FileListerFileInfo).GetProperties(); for (int i = 0; i < insertComm.Parameters.Count; i++) insertComm.Parameters[i].Value = properties[i].GetValue(file, null); /* Add the record. */ insertComm.ExecuteNonQuery(); return true; } 

编辑:

不,我根本不使用Excel。 我故意避免Interop.Excel,因为它的性能差(至less从我的涉猎)。

答案是肯定的 ,你所描述的公式确实相当不好。

如果您有一个方便的数据库(SQL Server或Access适用于此),则可以将所有插入到数据库表中,然后一次将所有表导出到Excel电子表格中。

一般来说,数据库擅长处理大量的插入,而电子表格则不是。

这里有几个想法:

目标工作簿是否打开? 有一个错误( 使用ActiveX数据对象查询打开的Excel工作表时发生内存泄漏 )IIRC实际上是在Jet(您正在使用)的OLE DB提供程序中,虽然这在上面的文章中未得到确认。

无论如何,批量插入似乎是要走的路。

您可以使用相同的Jet OLE DB提供程序来执行此操作:您只需要一行表。 你甚至可以在飞行中制作一个。 要创build新的Excel工作簿,请使用连接string中不存在的xls文件执行CREATE TABLE DDL,然后提供程序将使用工作表为您创build工作簿来表示该表。 你有一个连接到你的Excel工作簿,所以你可以执行此操作:

 CREATE TABLE [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable ( x FLOAT ); 

(甚至更好的IMO将是制造一个Jet数据库,即.mdb文件)。

使用INSERT来创build一个虚拟行:

 INSERT INTO [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable (x) VALUES (0); 

然后,仍然使用到目标工作簿的连接,可以使用类似于以下内容的方法在一次匹配中创build一个到INSERT的值的派生表(DT1):

 INSERT INTO MyExcelTable (key_col, data_col) SELECT DT1.key_col, DT1.data_col FROM ( SELECT 22 AS key_col, 'abc' AS data_col FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable UNION ALL SELECT 55 AS key_col, 'xyz' AS data_col FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable UNION ALL SELECT 99 AS key_col, 'efg' AS data_col FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable ) AS DT1; 

您不是一次写一条logging,而是可以find一种插入散装容量的方法? 我尽量不使用疯狂的DataSet的东西,但没有办法使所有的插入事件本地发生,然后让它们一举起来? 这个过程是否在后台打开Excel? 之后这些进程死了吗?