我目前正在将多个 Access 数据库转换为 Xml 文件。我以前做过这个,我仍然有以前项目的代码。但是,这段代码不会让我随心所欲地构建 xml,这是我这次需要做的。我正在使用XDocument
with for
-loops 来实现这一点,但是在 1000 行数据之后它变得非常慢。
阅读 XDocument 的工作原理告诉我XElement.Add
实际上复制了整个 xml 代码并在将所有内容粘贴回文件时添加了新元素。如果这是真的,那么这可能就是问题所在。
这是从Access中读写数据到Xml的部分,看看有没有办法保存。转换具有 27 列和 12256 行的数据库需要将近 30 分钟,而只有 500 行的较小数据库大约需要 5 秒。
private void ReadWrite(string file)
{
using (_Connection = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Mode=12;Data Source={0}", pathAccess)))
{
_Connection.Open();
//Gives me values from the AccessDB: tableName, columnName, colCount, rowCount and listOfTimeStamps.
GetValues(pathAccess);
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "true"), new XElement(tableName));
for (int rowInt = 0; rowInt < rowCount; rowInt++)
{
XElement item = new XElement("Item", new XAttribute("Time", listOfTimestamps[rowInt].ToString().Replace(" ", "_")));
doc.Root.Add(item);
//colCount"-1" prevents the timestamp from beeing written again.
for (int colInt = 0; colInt < colCount - 1; colInt++)
{
using (OleDbCommand cmnd = new OleDbCommand(string.Format("SELECT {0} FROM {1} Where TimeStamp = #{2}#", columnName[colInt] , tableName, listOfTimestamps[rowInt]), _Connection))
{
XElement value = new XElement(columnName[colInt], cmnd.ExecuteScalar().ToString());
item.Add(value);
}
}
//Updates progressbar
backgroundWorker1.ReportProgress(rowInt);
}
backgroundWorker1.ReportProgress(0);
doc.Save(file);
}
}
这是我的旧转换器的代码。这段代码几乎不受数据库大小的影响,12 556 数据库只需要一秒钟的时间来转换。有没有办法合并这两者?
public void ReadWrite2(string file)
{
DataSet dataSet = new DataSet();
using (_Connection = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Mode=12;Data Source={0}", file)))
{
_Connection.Open();
DataTable schemaTable = _Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
foreach (DataRow dataTableRow in schemaTable.Rows)
{
string tableName = dataTableRow["Table_Name"].ToString();
DataTable dataTable = dataSet.Tables.Add(tableName);
using (OleDbCommand readRows = new OleDbCommand("SELECT * from " + tableName, _Connection))
{
OleDbDataAdapter adapter = new OleDbDataAdapter(readRows);
adapter.Fill(dataTable);
}
}
}
dataSet.WriteXml(file.Replace(".mdb", ".xml"));
}
编辑:为了澄清,应用程序在执行时会变慢。无论数据库有多大,前 500 次都需要 5 秒。
更新:好的,所以我现在周末回来了,我在代码中做了一个小的调整,通过在一个循环中填充一个锯齿状数组并将它们写入另一个循环中的值来分离读取和写入。这证明了我的理论是错误的,事实上阅读需要花费很多时间。关于如何在不访问循环内的数据库的情况下用值填充数组的任何想法?
UPDATE2:这是切换到DataReader.Read()
-loop 并立即收集所有数据后的最终结果。
public void ReadWrite3(string Save, string Load)
{
using (_Connection = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Mode=12;Data Source={0}", Load)))
{
_Connection.Open();
GetValues(_Connection);
_Command = new OleDbCommand(String.Format("SELECT {0} FROM {1}", strColumns, tables), _Connection);
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "true"), new XElement("plmslog", new XAttribute("machineid", root)));
using (_DataReader = _Command.ExecuteReader())
{
for (int rowInt = 0; _DataReader.Read(); rowInt++ )
{
for (int logInt = 0; logInt < colCount; logInt++)
{
XElement log = new XElement("log");
doc.Root.Add(log);
elementValues = updateElementValues(rowInt, logInt);
for (int valInt = 0; valInt < elements.Length; valInt++)
{
XElement value = new XElement(elements[valInt], elementValues[valInt]);
log.Add(value);
}
}
}
}
doc.Save(Save);
}
}