今回は、C#のDataTableの使い方と、追加・更新・削除の具体的な方法をご紹介します。
DataTableとは
DataTableは、メモリ上で表形式のデータを扱うためのクラスです。
データベースから取得したデータの一時的な格納や、データの集計処理、データバインドなどで活用できます。
各行(DataRow)と列(DataColumn)の状態管理(RowState)や、変更履歴の追跡などを行える点が特徴です。
DataTableの基本的な使い方
まずはDataTableのインスタンスを生成し、必要な列情報(カラム)を定義します。
カラムごとに名前や型(int、stringなど)を設定し、行を追加する準備を整えます。
以下では、テーブルに「ID」「Name」「Age」という3つのカラムを用意します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System; using System.Data; class DataTableBasicUsage { static void Main() { // DataTableを作成し、テーブル名を設定 DataTable table = new DataTable("Employees"); // カラムを定義 table.Columns.Add("ID", typeof(int)); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Age", typeof(int)); // カラム情報を確認してコンソールに出力 foreach (DataColumn col in table.Columns) { Console.WriteLine("Column Name: " + col.ColumnName + ", Data Type: " + col.DataType); } } } |
Column Name: ID, Data Type: System.Int32
Column Name: Name, Data Type: System.String
Column Name: Age, Data Type: System.Int32
上記のようにカラムを定義することで、DataTableに表の構造が作られます。
Dataの追加・更新・削除
ここでは、作成したDataTableに対して、データを追加(Insert)、更新(Update)、削除(Delete)する方法を紹介します。
操作が終わったらAcceptChanges()を呼び出すことで、変更状態(RowState)をリセットできます。
データの追加(Insert)
新しい行を追加する方法には、主に以下の2パターンがあります。
- NewRow()で空の行を生成し、Rows.Add()でテーブルに追加
- Rows.Add(…)に値を直接渡す
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
using System; using System.Data; class DataTableInsertDemo { static void Main() { // DataTableの生成とカラム定義 DataTable table = new DataTable("Employees"); table.Columns.Add("ID", typeof(int)); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Age", typeof(int)); // NewRowを使った行追加 DataRow row1 = table.NewRow(); row1["ID"] = 1; row1["Name"] = "Alice"; row1["Age"] = 28; table.Rows.Add(row1); // Rows.Add(...)に値を直接指定 table.Rows.Add(2, "Bob", 35); // 登録したデータを表示 foreach (DataRow row in table.Rows) { Console.WriteLine("ID: " + row["ID"] + ", Name: " + row["Name"] + ", Age: " + row["Age"]); } } } |
ID: 1, Name: Alice, Age: 28
ID: 2, Name: Bob, Age: 35
データの更新(Update)
行を検索して該当データを特定し、列の値を変更します。
DataTable.Select(“条件”)で行を検索し、見つかった行のカラムを更新するイメージです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
using System; using System.Data; class DataTableUpdateDemo { static void Main() { // DataTableの生成と初期データの追加 DataTable table = new DataTable("Employees"); table.Columns.Add("ID", typeof(int)); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Age", typeof(int)); table.Rows.Add(1, "Alice", 28); table.Rows.Add(2, "Bob", 35); // IDが1の行を検索してNameを更新 DataRow[] result = table.Select("ID = 1"); if (result.Length > 0) { result[0]["Name"] = "Alice Smith"; } // 更新後のデータ表示 foreach (DataRow row in table.Rows) { Console.WriteLine("ID: " + row["ID"] + ", Name: " + row["Name"] + ", Age: " + row["Age"]); } } } |
ID: 1, Name: Alice Smith, Age: 28
ID: 2, Name: Bob, Age: 35
データの削除(Delete)
Delete()を使った方法では、行が「Deleted」状態となり、その後にAcceptChanges()を呼ぶと完全に削除されます。
RemoveAt()を使う場合は、その行が即時にコレクションから取り除かれます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using System; using System.Data; class DataTableDeleteDemo { static void Main() { // DataTableの生成と初期データの追加 DataTable table = new DataTable("Employees"); table.Columns.Add("ID", typeof(int)); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Age", typeof(int)); table.Rows.Add(1, "Alice", 28); table.Rows.Add(2, "Bob", 35); // IDが2の行をDelete()で削除(論理削除) DataRow[] rowsToDelete = table.Select("ID = 2"); if (rowsToDelete.Length > 0) { rowsToDelete[0].Delete(); } // 状態を確定(Deleted状態の行が物理的に削除される) table.AcceptChanges(); // 削除後のデータ表示 foreach (DataRow row in table.Rows) { Console.WriteLine("ID: " + row["ID"] + ", Name: " + row["Name"] + ", Age: " + row["Age"]); } } } |
ID: 1, Name: Alice, Age: 28
注意点
RowStateの管理に注意する必要があります。
たとえば、行を削除する際にDelete()を使った場合は、その行の状態が「Deleted」になり、AcceptChanges()を呼ぶと完全に削除されます。
Remove()やRemoveAt()を使った場合は、変更履歴を残さず即座に行を取り除くため、後から差分を確認したいときなどには不向きです。
また、複数スレッドから同時にDataTableを操作する場合は、排他制御やスレッドセーフな設計が必要です。
まとめ
DataTableを利用すれば、表形式のデータをメモリ上で柔軟に取り扱えます。
カラムを定義してデータを追加・更新・削除する流れを覚えておくと、データ操作の効率が大幅に向上します。
RowStateやAcceptChanges()などのメソッドを理解し、状況に応じて使い分けることが大切です。