2015/05/17

[C#]DataTableをさくっとつくるには

このエントリーをはてなブックマークに追加
何かと便利なDataTableです。
DataTableを扱って何かするときに、慣れれば難しいところはありませんが、とにかく冗長的な印象があります。
まずダミーデータの準備に労力が費やされてしまうことがあって、結構面倒なのです。
そういうDataTableについて、ちょこっと記法に気を付けることで、記述内容を大幅に削減してしまおうというのがこのエントリのテーマです。

DataTableを作成するためのコード

DataTableの作成は①DataColumnを追加して列(スキーマ)を準備、そのあと②データを格納させるDataRowを追加する必要があります。

DataColumnを追加して列(スキーマ)を準備
まず、DataTableのインスタンスをつくる。これはそのまま。
DataTable table = new DataTable();

列となるDataColumnを追加します。
個人情報のようなものが格納されるとして、普通は、こんな感じになりますね。
table.Columns.Add(new DataColumn("name"));
table.Columns.Add(new DataColumn("ruby"));
table.Columns.Add(new DataColumn("sex"));
table.Columns.Add(new DataColumn("age"));
table.Columns.Add(new DataColumn("birthday"));
table.Columns.Add(new DataColumn("married"));
table.Columns.Add(new DataColumn("prefecture"));

はい、これ。
工夫すると、こう書けます。
string[] columnList = { "name", "ruby", "sex", "age", "birthday", "married", "prefecture"};
table.Columns.AddRange(columnList.Select(n => new DataColumn(n)).ToArray());
文字列の配列をもとに、DataColumnの配列を作って一気に追加しています。
たった2行に収まりました。もちろん強引に1行にもできます。

データを格納させるDataRowを追加する
次に、行となるDataRowを追加します。
DataTableに準備した列(スキーマ)に合わせた行を作成するので、DataTableのNewRowメソッドを呼び出して、新しい行になるDataRowを拾ってあげます。
DataRowに設定する値を入れて、改めて、DataTableのRowsプロパティに追加する。
(覚えたてのとき、自分にはこの操作が意味不明でした)
コードにすると、こんな感じです。
DataRow row = table.NewRow();
row["name"] = "三村 瑠璃亜";
row["ruby"] = "みむら るりあ";
row["sex"] = "女";
row["age"] = "32";
row["birthday"] = "1982/7/16";
row["married"] = "既婚";
row["prefecture"] = "茨城県";
table.Rows.Add(row);
これで1個のデータです。結構なカタマリになります。

DataTableのRowsプロパティのAddメソッドには、オーバーロードとしてobject[]を指定することができます。
なので、上のカタマリは、下記のように書いてもいいのです。
table.Rows.Add("三村 瑠璃亜", "みむら るりあ", "女", "32", "1982/7/16", "既婚", "茨城県");
はい、1行です。
行に追加した順番に気を付ける必要がありますが、テストパターンとして内容に変化を付けるときなどは、こちらのほうが見やすいようにも思います。
もちろん、テストデータらしく、hogehogeとかaaaとかだったら、どの列のデータなのかは見失いやすいので注意が必要ですが…。

サンプルコード
ということでざっとDataTableのダミーデータを作成するためのサンプルコードを載せておきます。

// DataTableのダミーデータを作成する

// DataColumnを追加して列(スキーマ)を準備
DataTable table = new DataTable();
string[] columnList = { "name", "ruby", "sex", "age", "birthday", "married", "prefecture"};
table.Columns.AddRange(columnList.Select(n => new DataColumn(n)).ToArray());

// データを格納させるDataRowを追加する
table.Rows.Add("三村 瑠璃亜", "みむら るりあ", "女", "32", "1982/7/16", "既婚", "茨城県");
table.Rows.Add("山崎 隆", "やまざき たかし", "男", "32", "1982/10/3", "未婚", "東京都");
table.Rows.Add("滝 慢太郎", "たき まんたろう", "男", "31", "1983/6/30", "未婚", "福岡県");
table.Rows.Add("石塚 浩正", "いしづか ひろま", "男", "29", "1985/3/1", "既婚", "熊本県");
table.Rows.Add("中西 光", "なかにし ひかる", "男", "55", "1959/2/22", "既婚", "福島県");
コピペコピペでNewRowメソッド呼び出しによる長く平坦な記述よりも、よっぽど表データっていう感じがしますね。

2015/05/09

[C#]クエリ文字列を操作する

このエントリーをはてなブックマークに追加
ご存じ、URLの後ろにくっついてるパラメータをクエリ文字列と言います。

クエリ文字列を扱うときにDictionaryに変換する自作関数をセコセコ作ったり、またくっつけるための関数を作ったり、そういう操作をしていたのですが、HttpUtility.ParseQueryStringメソッドでまるっと操作できるようです。

HttpUtility.ParseQueryStringメソッドを使う

HttpUtility.ParseQueryStringメソッドはクエリ文字列を引数に、NameValueCollectionオブジェクトを返します。
NameValueCollectionは、Dictionary型のようにキーより値が参照できます。
HttpUtility.ParseQueryStringメソッドが返すNameValueCollectionは、ToStringメソッドで、&と=でつなげたクエリ文字列がそのまま返ります。部分的に値を変更して改めてクエリ文字をつくるような操作もお手の物です。

サンプルコード
// using System.Web;
// using System.Collections.Specialized
// ダミーのURLです
string url = "http://www.hogehoge.co.jp/index.htm?var1=%u3042%u3044%u3046%u3048%u304a&var2=abc&var3=12345";
Uri uri = new Uri(url);
string queryString = uri.Query;

Console.WriteLine(queryString);
// ?var1=%25u3042%25u3044%25u3046%25u3048%25u304a&var2=abc&var3=12345

// ①クエリ文字列からNameValueCollectionを生成
NameValueCollection query = HttpUtility.ParseQueryString(queryString,Encoding.UTF8);

// ②クエリの値を確認
foreach(string key in query.Keys){
    Console.WriteLine(key + "=" + HttpUtility.UrlDecode(query[key]));
}
// var1=あいうえお
// var2=abc
// var3=12345

// ③クエリの値を変更
query["var1"] = "かきくけこ";

// ④クエリ文字列を再生成
Console.WriteLine(query.ToString());
// var1=%u304b%u304d%u304f%u3051%u3053&var2=abc&var3=12345

コードの解説
①クエリ文字列からNameValueCollectionを生成
ダミーURLをもとに、HttpUtility.ParseQueryStringメソッドを使用してクエリ文字列からNameValueCollectionを生成します。

②クエリの値を確認
NameValueCollectionオブジェクトに値がどのように格納されているかクエリの値を確認します。

③クエリの値を変更
キー(var1)に対応するクエリの値を変更します。

④クエリ文字を再生成
NameValueCollectionオブジェクトのToStringメソッドを呼び出すと、=と&で結合されたクエリ文字列が生成されます。


NameValueCollectionはSystem.Collections.Specializedというあまり聞きなれない名前空間にあります。
HttpUtility.ParseQueryStringメソッドのために、using System.Web;が必要です。(要System.Web.dll参照)

NameValueCollectionをDictionaryに変換する

NameValueCollectionはDictionaryに似ているのですが、Linqが使えません。
何かとDictionary形式のほうが使い勝手がいいとお考えの人は、変換してあげてください。

Dictionary<string,string> dic = query.Keys.Cast<string>().ToDictionary(n => n, m => query[m]);

それではよきクエリ文字ライフを!