0

DataAdapterの使用で問題が発生しました。誰かが助けてくれることを願っています。基本的に私は次のようなシステムを作成しています。

  1. データはデータソース(MS-Access、SQL Server、またはExcel)から読み込まれ、データテーブルに変換され、DataAdaptersを使用してローカルのSQLServerデータベースに挿入されます。このビットは正常に機能します。SQLサーバーテーブルにはPKがあります。これは、自動インクリメントがオンに設定されたIDフィールドです。
  2. 後続のデータロードは、ソースからデータを読み込み、それを既存のデータと比較します。レコードが欠落している場合は、追加されます(これは正常に機能します)。レコードが異なる場合は、更新する必要があります(これは機能しません)。
  3. 差分データロードを実行するときは、宛先テーブル(SQLサーバー)からスキーマを読み取り、同じ列などがあることを確認するデータテーブルを作成します。
  4. 宛先テーブルのPKは列0であるため、レコードが挿入されると、列1以降のすべての値が設定されます(前述のように、これは完全に機能します)。追加するアイテムの行ステータスは変更しません。データテーブルのPKが正しく設定されており、確認できます。
  5. データを更新するときは、列0(PK列)を更新するレコードの値に設定し、すべての列をソースデータと同じに設定します。
  6. 更新されたレコードの場合、行でAcceptChangesとSetModifiedを呼び出して、アプリケーションが正しいメソッドを呼び出すことを確認します(私は思った)。
  7. 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;
    }
4

1 に答える 1

1

誰かが興味を持っている場合に備えて、問題を回避することはできましたが、データ アダプターを動作させることはできませんでした。基本的に私がしたことは次のとおりです。

  • メンバーとしてインデックスとフィールド値のリストを持つオブジェクトのリストを作成します
  • 変更された行を読み取り、ソース データからの値 (つまり、オブジェクト内の現在の値を上書きする値) を格納します。さらに、インデックスのコンマ区切りリストを作成します
  • 終了したら、SQL IN ステートメントでコンマ区切りのリストを使用して行を返し、データ アダプターに読み込みます。
  • それぞれについて、インデックスに対して LINQ クエリを実行し、新しい値を抽出してデータ セットを更新します。これにより、行のステータスが変更済みに設定されます
  • その後、更新を実行すると、行が正しく更新されます。

これは最速または最も適切なソリューションではありませんが、機能し、バッチで変更を実行できます。

ありがとう

アンドリュー

于 2012-08-14T07:09:15.507 に答える