現在、多数の Access データベースを Xml ファイルに変換中です。以前にこれを行ったことがありますが、以前のプロジェクトのコードがまだ残っています。ただし、このコードでは、XML を思い通りに構成できません。これは、今回行う必要があることです。XDocument
これを実現するために with for
-loops を使用していますが、データが 1000 行になると非常に遅くなります。
XDocument がどのように機能するかを読むと、XElement.Add
実際には xml コード全体をコピーし、すべてをファイルに貼り付けるときに新しい要素を追加することがわかります。これが本当なら、おそらく問題はそこにあります。
これは、Access から Xml へのデータの読み取りと書き込みを行う部分です。保存する方法があるかどうかを確認してください。27 列と 12,256 行のデータベースの変換には約 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 データベースの変換には 1 秒しかかかりません。これら2つをマージする方法はありますか?
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 秒かかります。
更新:わかりましたので、週末の後に戻ってきました。コードを少し調整して、1 つのループでギザギザの配列に値を入力し、別のループで値を書き込むことで、読み取りと書き込みを分離しました。これは私の理論が間違っていることを証明しており、実際には非常に時間がかかるのは読書です. ループ内でデータベースにアクセスせずに配列に値を入力する方法についてのアイデアはありますか?
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);
}
}