C#
.NET

DataRow から値を読み書きする

More than 3 years have passed since last update.

意外と知られていない気がするので。

.NET Framework 3.5 から DataRowExtensions というクラスで DataRow オブジェクトに対する値の読み書きが強化されました。

使用するためには System.Data.DataSetExtensions を参照に追加してください。

DataTable table = GetDataTable();

// 値の読み取り
string value = table.Rows[0].Field<string>("hoge_id");

// 値の書き込み
table.Rows[0].SetField("hoge_name", "ほげほげ");

これの何がいいかというと、これまでのインデクサを使用する方法で必要だった DBNull の考慮が不要になります。

DataTable table = GetDataTable();

// DBNull.Value が格納されていた場合 InvalidCastException がスローされる
string value = (string)table.Rows[0]["hoge_id"];
// なので書くならこう↓↓ ダサい!抱かないで!
// string value = (string)(DBNull.Value.Equals(table.Rows[0]["hoge_id"]) ? null : table.Rows[0]["hoge_id"]);

// System.ArgumentException: 列'hoge_name'をNullに設定できません。DBNullを使用してください。
string hogeName = null;
table.Rows[0]["hoge_name"] = hogeName;
// なので書くならこう↓↓ ダサい!○んで!(object 型へのキャストがないと null 合体演算子が型を解決できない)
// table.Rows[0]["hoge_name"] = hogeName ?? (object)DBNull.Value;

また、こちらは割と知られている気がしますが、DataTableExtensions というクラスで Rows プロパティの列挙がサポートされています。

DataTable table = GetDataTable();

var records = from row in table.AsEnumerable()
select new
{
Id = row.Field<string>("hoge_id"),
Name = row.Field<string>("hoge_name") ?? "名無しさん"
};

DataTable もこれらのメソッドを使って LINQ で処理すれば少しは付き合いやすくなる…かも?