【C#.NET解説】DataTableの基礎を解き明かす 〜大気の女神が教える究極ガイド

2024年11月25日月曜日

コレクション データベース

t f B! P L

名前空間 System.Data

自己紹介

私は大気を司る女神です。皆さん、今日は私「DataTable」クラスについてお話しします。このクラスはデータをテーブル形式で扱うための便利な機能が詰まっていますよ。まるで私が空気を調和させるように、データを整理し、整える力を持っているのです。

基本機能とサンプルコード

DataTableは、データを行と列で構成されたテーブルとして操作するためのクラスです。データの追加や削除、検索、フィルタリングなど、データ操作に必要な機能が揃っています。

C#

// DataTableの基本的な使い方
using System;
using System.Data;

class Program
{
    static void Main()
    {
        // DataTableを作成
        DataTable table = new DataTable("SampleTable");

        // 列を追加
        table.Columns.Add("ID", typeof(int));
        table.Columns.Add("Name", typeof(string));

        // 行を追加
        table.Rows.Add(1, "りんご");
        table.Rows.Add(2, "みかん");

        // テーブル内容を表示
        foreach (DataRow row in table.Rows)
        {
            Console.WriteLine($"ID: {row["ID"]}, Name: {row["Name"]}");
        }
    }
}

注意点とサンプルコード

DataTableを使用する際の注意点は、パフォーマンスとメモリ消費です。大量のデータを扱うと処理速度が遅くなることがありますので、使用するデータ量には注意してください。

C#

// DataTableのフィルタリング
using System;
using System.Data;

class Program
{
    static void Main()
    {
        DataTable table = new DataTable();
        table.Columns.Add("ID", typeof(int));
        table.Columns.Add("Name", typeof(string));

        table.Rows.Add(1, "みかん");
        table.Rows.Add(2, "バナナ");

        // フィルタリング
        DataRow[] filteredRows = table.Select("Name = 'みかん'");

        foreach (DataRow row in filteredRows)
        {
            Console.WriteLine($"Filtered ID: {row["ID"]}, Name: {row["Name"]}");
        }
    }
}

速度向上のための工夫

DataTableを効率的に利用するには、必要最小限のデータ列を使い、適切な型を設定することが重要です。また、頻繁にアクセスする場合は、キャッシュや一時的なデータ構造を検討すると良いでしょう。

C#

// 大量データを扱う際の最適化例
using System;
using System.Data;

class Program
{
    static void Main()
    {
        DataTable table = new DataTable();

        table.Columns.Add("ID", typeof(int));
        table.Columns.Add("Value", typeof(double));
        // あらかじめ行数がわかるなら容量を拡張して、頻繁な再割り当てを回避
        table.MinimumCapacity = 1000000;
        
        dataTable.BeginLoadData(); // 更新の一時停止
        // 大量データを効率的に追加
        for (int i = 0; i < 1000000; i++)
        {
            table.Rows.Add(i, Math.Sqrt(i));
        }
        dataTable.EndLoadData(); // 更新の再開

        Console.WriteLine("データの追加が完了しました。");
    }
}

次に、プライマリキーを設定したパターンでの速度向上の例です。

C#

using System;
using System.Data;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        // プライマリキーを設定したDataTable
        DataTable dataTableWithKey = new DataTable("WithKey");
        DataColumn column1 = new DataColumn("Column1", typeof(int));
        DataColumn column2 = new DataColumn("Column2", typeof(string));
        dataTableWithKey.Columns.Add(column1);
        dataTableWithKey.Columns.Add(column2);
        dataTableWithKey.PrimaryKey = new DataColumn[] { column1, column2 };

        // プライマリキーを設定していないDataTable
        DataTable dataTableWithoutKey = new DataTable("WithoutKey");
        DataColumn col1 = new DataColumn("Column1", typeof(int));
        DataColumn col2 = new DataColumn("Column2", typeof(string));
        dataTableWithoutKey.Columns.Add(col1);
        dataTableWithoutKey.Columns.Add(col2);

        // データの追加
        AddData(dataTableWithKey);
        AddData(dataTableWithoutKey);

        // 検索キー
        object[] searchKey = new object[] { 50000, "Value 50000" };

        // プライマリキーを使用した検索
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();
        DataRow foundRowWithKey = dataTableWithKey.Rows.Find(searchKey);
        stopwatch.Stop();
        Console.WriteLine($"With Primary Key: {stopwatch.ElapsedMilliseconds} ms");

        // プライマリキーを使用していない検索
        stopwatch.Reset();
        stopwatch.Start();
        DataRow foundRowWithoutKey = null;
        foreach (DataRow row in dataTableWithoutKey.Rows)
        {
            if ((int)row["Column1"] == (int)searchKey[0] && (string)row["Column2"] == (string)searchKey[1])
            {
                foundRowWithoutKey = row;
                break;
            }
        }
        stopwatch.Stop();
        Console.WriteLine($"Without Primary Key: {stopwatch.ElapsedMilliseconds} ms");
    }

    static void AddData(DataTable dataTable)
    {
        for (int i = 0; i < 100000; i++)
        {
            DataRow row = dataTable.NewRow();
            row["Column1"] = i;
            row["Column2"] = $"Value {i}";
            dataTable.Rows.Add(row);
        }
    }
}

具体的な使い方

DataTableを使用して、データベースから取得した情報をアプリケーション内で操作するケースをご紹介します。

C#

// SQLデータをDataTableにロードして操作する例
using System;
using System.Data;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connectionString = "your_connection_string_here";
        string query = "SELECT ID, Name FROM SampleTable";

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            SqlDataAdapter adapter = new SqlDataAdapter(query, connection);
            DataTable table = new DataTable();

            adapter.Fill(table);

            foreach (DataRow row in table.Rows)
            {
                Console.WriteLine($"ID: {row["ID"]}, Name: {row["Name"]}");
            }
        }
    }
}

解説

上記のコードでは、SQLデータをDataTableにロードし、各行のデータを操作しています。この方法は、データベースから取得したデータをアプリケーション内で効率的に扱う際に非常に便利です。DataAdapterを使用してDataTableにデータをロードすることで、クエリの結果を簡単に取得できます。

このブログを検索

QooQ