gpt4 book ai didi

c# - 为什么这段代码变慢了?

转载 作者:数据小太阳 更新时间:2023-10-29 02:03:57 25 4
gpt4 key购买 nike

我目前正在将大量 Access 数据库转换为 Xml 文件。我以前做过这个,我仍然有以前项目的代码。但是,此代码不会让我随心所欲地构造 xml,而这正是我这次需要做的。我使用带有 for 循环的 XDocument 来实现这一点,但是在 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 秒。

更新: 好吧,周末过后我回来了,我对代码做了一个小调整,通过在一个循环中用值填充锯齿状数组来分离读取和写入并将它们写在另一个。这证明我的理论是错误的,实际上是阅读花费了这么多时间。关于如何在不 Access 循环内的数据库的情况下用值填充数组的任何想法?

UPDATE2:这是切换到 DataReader.Read() 循环并立即收集所有数据后的最终结果。

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);
}
}

最佳答案

请原谅我,但我认为你让你的生活变得比它需要的更复杂。如果您使用 OleDbDataReader 对象,您只需打开它并逐行读取 Access 表,而不必将行数据缓存在数组中(因为您已经在 DataReader 中拥有它)。

比如我有一些样本数据

dbID    dbName  dbCreated
---- ------ ---------
bar barDB 2013-04-08 14:19:27
foo fooDB 2013-04-05 11:23:02

下面的代码贯穿整个表...

static void Main(string[] args)
{
OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Documents and Settings\Administrator\Desktop\Database1.accdb;");
conn.Open();

OleDbCommand cmd = new OleDbCommand("SELECT * FROM myTable", conn);
OleDbDataReader rdr = cmd.ExecuteReader();

int rowNumber = 0;
while (rdr.Read())
{
rowNumber++;
Console.WriteLine("Row " + rowNumber.ToString() + ":");
for (int colIdx = 0; colIdx < rdr.FieldCount; colIdx++)
{
string colName = rdr.GetName(colIdx);
Console.WriteLine(" rdr[\"" + colName + "\"]: " + rdr[colName].ToString());
}
}
rdr.Close();
conn.Close();

Console.WriteLine("Done.");
}

...并产生结果...

Row 1:
rdr["dbID"]: foo
rdr["dbName"]: fooDB
rdr["dbCreated"]: 2013-04-05 11:23:02
Row 2:
rdr["dbID"]: bar
rdr["dbName"]: barDB
rdr["dbCreated"]: 2013-04-08 14:19:27
Done.

关于c# - 为什么这段代码变慢了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15828984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com