.NET Framework を使用してデータセット内のデータを編集する

Note

データセットと関連クラスは、アプリケーションがデータベースから切断されている間にアプリケーションがメモリ内のデータを操作できるようにする、2000 年代初期からのレガシ .NET Framework テクノロジです。 これらが特に役立つのは、ユーザーがデータを変更し、変更をデータベースに戻して保持できるようにするアプリケーションです。 データセットは非常に優れたテクノロジであることが証明されていますが、新しい .NET アプリケーションでは Entity Framework Core を使用することをお勧めしています。 Entity Framework には、オブジェクト モデルとして表形式データを操作する、より自然な方法が用意されており、よりシンプルなプログラミング インターフェイスが備わっています。

データ テーブル内のデータは、任意のデータベースのテーブルのデータを編集するのとほとんど同様に編集できます。 このプロセスには、テーブル内のレコードの挿入、更新、および削除を含めることができます。 データバインド フォームで、ユーザーが編集できるフィールドを指定できます。 このような場合、後で変更をデータベースに返送できるように、データ バインディング インフラストラクチャによって、すべての変更追跡が処理されます。 プログラムによってデータを編集し、それらの変更をデータベースに返送する場合は、自動的に変更の追跡を行うオブジェクトとメソッドを使用する必要があります。

実際のデータを変更するだけでなく、DataTable をクエリして、特定のデータ行を返すこともできます。 たとえば、個々の行、特定のバージョンの行 (元の列と提案された行)、変更された行、またはエラーが発生した行に対してクエリできます。

データセット内の行を編集するには

DataTable の既存の行を編集するには、編集する DataRow を検索し、更新した値を目的の列に割り当てる必要があります。

編集する行のインデックスがわからない場合は、FindBy メソッドを使用して、主キーで検索します。

NorthwindDataSet.CustomersRow customersRow = 
    northwindDataSet1.Customers.FindByCustomerID("ALFKI");

customersRow.CompanyName = "Updated Company Name";
customersRow.City = "Seattle";

行インデックスがわかっている場合は、次のように行にアクセスして編集できます。

northwindDataSet1.Customers[4].CompanyName = "Updated Company Name";
northwindDataSet1.Customers[4].City = "Seattle";

データセットに新しい行を挿入するには

データバインド コントロールを使用するアプリケーションでは、通常 BindingNavigator コントロール[新規追加] ボタンを使用して、新しいレコードを追加します。

新しいレコードをデータセットに手動で追加するには、DataTable に対してメソッドを呼び出して、新しいデータ行を作成します。 次に、DataTableDataRow コレクション (Rows) に行を追加します。

NorthwindDataSet.CustomersRow newCustomersRow = 
    northwindDataSet1.Customers.NewCustomersRow();

newCustomersRow.CustomerID = "ALFKI";
newCustomersRow.CompanyName = "Alfreds Futterkiste";

northwindDataSet1.Customers.Rows.Add(newCustomersRow);

データセットで、データ ソースに更新を送信するために必要な情報を保持するには、Delete メソッドを使用して、データ テーブル内の行を削除します。 たとえば、アプリケーションで TableAdapter (または DataAdapter) を使用している場合、TableAdapter の Update メソッドによって、RowStateDeleted であるデータベース内の行を削除します。

アプリケーションでデータ ソースに更新を返送する必要がない場合は、データ行コレクションに直接アクセスして、レコードを削除できます (Remove)。

データ テーブルからレコードを削除するには

  • DataRowDelete メソッドを呼び出します。

    このメソッドでは、物理的にレコードが削除されません。 代わりに、レコードが削除対象としてマークされます。

    注意

    DataRowCollection のカウント プロパティを取得すると、結果のカウントには、削除対象としてマークされたレコードが含まれます。 削除対象としてマークされていないレコードの正確なカウントを取得するには、コレクションをループ処理して、各レコードの RowState プロパティを調べます。 (削除対象としてマークされたレコードは、RowStateDeleted になっています)。または、行の状態に基づいてフィルター処理するデータセットのデータ ビューを作成し、そこからカウント プロパティを取得することもできます。

次の例に、Delete メソッドを呼び出して、Customers テーブルの最初の行を削除済みとしてマークする方法を示します。

northwindDataSet1.Customers.Rows[0].Delete();

変更された行があるかどうかを判断する

データセット内のレコードを変更すると、その変更をコミットするまで変更情報が保持されます。 データセットまたはデータ テーブルの AcceptChanges メソッドを呼び出すか、TableAdapter またはデータ アダプターの Update メソッドを呼び出す場合、変更をコミットします。

変更は各データ行で 2 とおりの方法で追跡されます。

  • 各データ行には、その RowState に関連する情報 (AddedModifiedDeletedUnchanged など) の情報が含まれます。

  • 変更された各データ行には、その行の複数のバージョン (DataRowVersion)、つまり元のバージョン (変更前) と現在のバージョン (変更後) が含まれます。 変更が保留されている期間 (RowChanging イベントに応答できる期間) は、3 つ目のバージョン (提案されたバージョン) も利用できます。

データセットが変更された場合、データセットの HasChanges メソッドでは、true が返されます。 変更された行が存在することを確認した後は、GetChanges または DataSetDataTable メソッドを呼び出して、変更された一連の行を取得できます。

行が変更されたかどうかを確認するには

  • データセットの HasChanges メソッドを呼び出し、変更された行があるかどうかをチェックします。

HasChanges メソッドから返された値をチェックし、NorthwindDataset1 という名前のデータセットが変更された行があるかどうかを確認する方法を次の例に示します。

if (northwindDataSet1.HasChanges()) 
{
    // Changed rows were detected, add appropriate code.
}
else
{
    // No changed rows were detected, add appropriate code.
}

変更の種類を確認する

DataRowState 列挙の値を HasChanges メソッドに渡すことにより、データセットに加えられた変更の種類を確認することもできます。

行への変更の種類を確認するには

次の例に、NorthwindDataset1 という名前のデータセットを確認し、新しく追加された行があるかどうかを判断する方法を示します:

if (northwindDataSet1.HasChanges(DataRowState.Added)) 
{
    // New rows have been added to the dataset, add appropriate code.
}
else
{
    // No new rows have been added to the dataset, add appropriate code.
}

エラーが発生している行を見つけるには

データの個々の列と行を操作している場合に、エラーが発生することがあります。 HasErrors プロパティをチェックして、DataSetDataTable、または DataRow にエラーが存在するかどうかを確認できます。

  1. HasErrors プロパティをチェックして、データセットに何らかのエラーがあるかどうかを確認します。

  2. HasErrors プロパティが true の場合は、テーブルのコレクションを反復処理し、次に行を反復処理して、エラーのある行を見つけます。

private void FindErrors() 
{
    if (dataSet1.HasErrors)
    {
        foreach (DataTable table in dataSet1.Tables)
        {
            if (table.HasErrors)
            {
                foreach (DataRow row in table.Rows)
                {
                    if (row.HasErrors)
                    {
                        // Process error here.
                    }
                }
            }
        }
    }
}