DataAdapterの使用で問題が発生しました。誰かが助けてくれることを願っています。基本的に私は次のようなシステムを作成しています。
- データはデータソース(MS-Access、SQL Server、またはExcel)から読み込まれ、データテーブルに変換され、DataAdaptersを使用してローカルのSQLServerデータベースに挿入されます。このビットは正常に機能します。SQLサーバーテーブルにはPKがあります。これは、自動インクリメントがオンに設定されたIDフィールドです。
- 後続のデータロードは、ソースからデータを読み込み、それを既存のデータと比較します。レコードが欠落している場合は、追加されます(これは正常に機能します)。レコードが異なる場合は、更新する必要があります(これは機能しません)。
- 差分データロードを実行するときは、宛先テーブル(SQLサーバー)からスキーマを読み取り、同じ列などがあることを確認するデータテーブルを作成します。
- 宛先テーブルのPKは列0であるため、レコードが挿入されると、列1以降のすべての値が設定されます(前述のように、これは完全に機能します)。追加するアイテムの行ステータスは変更しません。データテーブルのPKが正しく設定されており、確認できます。
- データを更新するときは、列0(PK列)を更新するレコードの値に設定し、すべての列をソースデータと同じに設定します。
- 更新されたレコードの場合、行でAcceptChangesとSetModifiedを呼び出して、アプリケーションが正しいメソッドを呼び出すことを確認します(私は思った)。
- DataAdapterは、コマンドビルダーを使用してSelectCommandおよびUpdateCommandで設定されます。
実行すると、SQLプロファイラーを使用してトレースし、挿入コマンドが正しく実行されていることを確認できますが、更新コマンドがまったく実行されていないことが問題の核心です。参考までに、挿入テーブルは次のようになります。
PK Value1 Value 2 Row State
== ====== ======= =========
124 Test1 Test 2 Added
123 Test3 Test4 Updated
注意すべき点がいくつかあります。
- 変更する行をデータテーブルにロードし、いくつかの列フィールドを変更して更新を実行することでこれをテストしましたが、これは機能します。ただし、これは私のソリューションでは実用的ではありません。データが1Gbを超えるため、パフォーマンスに大きな影響を与えずにデータテーブルにロードすることはできません。私が行っているのは、最大500行のデータテーブルを作成し、更新を実行することです。初期データロード中のテストでは、これがメモリ使用量とパフォーマンスの点で最も効率的であることが示されました。データテーブルは、各バッチが実行された後にクリアされます。
私がここで間違っているところについて誰かアイデアはありますか?
前もって感謝します
アンドリュー
==========更新==============
以下は、挿入/更新行を作成するためのコードです
private static void AddNewRecordToDataTable(DbDataReader pReader, ref DataTable pUpdateDataTable)
{
// create a new row in the table
DataRow pUpdateRow = pUpdateDataTable.NewRow();
// loop through each item in the data reader - setting all the columns apart from the PK
for (int addCount = 0; addCount < pReader.FieldCount; addCount++)
{
pUpdateRow[addCount + 1] = pReader[addCount];
}
// add the row to the update table
pUpdateDataTable.Rows.Add(pUpdateRow);
}
private static void AddUpdateRecordToDataTable(DbDataReader pReader, int pKeyValue,
ref DataTable pUpdateDataTable)
{
DataRow pUpdateRow = pUpdateDataTable.NewRow();
// set the first column (PK) to the value passed in
pUpdateRow[0] = pKeyValue;
// loop for each row apart from the PK row
for (int addCount = 0; addCount < pReader.FieldCount; addCount++)
{
pUpdateRow[addCount + 1] = pReader[addCount];
}
// add the row to the table and then update it
pUpdateDataTable.Rows.Add(pUpdateRow);
pUpdateRow.AcceptChanges();
pUpdateRow.SetModified();
}
次のコードは、実際に更新を行うために使用されます。
updateAdapter.Fill(UpdateTable);
updateAdapter.Update(UpdateTable);
UpdateTable.AcceptChanges();
以下は、データテーブルを作成して、ソースデータと同じフィールド/データタイプを持つようにするために使用されます
private static DataTable CreateDataTable(DbDataReader pReader)
{
DataTable schemaTable = pReader.GetSchemaTable();
DataTable resultTable = new DataTable(<tableName>); // edited out personal info
// loop for each row in the schema table
try
{
foreach (DataRow dataRow in schemaTable.Rows)
{
// create a new DataColumn object and set values depending
// on the current DataRows values
DataColumn dataColumn = new DataColumn();
dataColumn.ColumnName = dataRow["ColumnName"].ToString();
dataColumn.DataType = Type.GetType(dataRow["DataType"].ToString());
dataColumn.ReadOnly = (bool)dataRow["IsReadOnly"];
dataColumn.AutoIncrement = (bool)dataRow["IsAutoIncrement"];
dataColumn.Unique = (bool)dataRow["IsUnique"];
resultTable.Columns.Add(dataColumn);
}
}
catch (Exception ex)
{
message = "Unable to create data table " + ex.Message;
throw new Exception(message, ex);
}
return resultTable;
}