#型付データセット
.Net FrameworkではDataSetをデザイナから生成すると、固有の型を持った型付DataSetを使用できるようになる。
ただ、Null許容型の列については、nullを値として返すことはできず、Nullチェックが必須になる。
(.Net 3.5からはDataRow.Field<>メソッドで対応可能)。
- サンプルコード
型付データセットに設定した
ID(int,必須),
Name(string,Null許容),
Address(string,Null許容),
年齢(int,Null許容)を
画面項目に設定しているコードについて考える。
var ds = new SampleDataSet();
var row = ds.Table[0];
row.ID = 1;
row.NAME = "名前";
row.ADDRESS = null;
row.SetAGENull();
labelID.Text = row.ID.ToString();
if (row.IsNAMENull())
{
labelName.Text = string.Empty;
}
else
{
labelName.Text = row.NAME;
}
if (row.IsADDRESSNull())
{
labelAddress.Text = string.Empty;
}
else
{
labelAddress.Text = row.ADDRESS;
}
if (row.IsAGENull())
{
labelAge.Text = string.Empty;
}
else
{
labelAge.Text = row.AGE.ToString();
}
- 簡潔に書きたい。
この程度であればNullチェックせずに代入したくなるが、Nullチェックしないと例外が発生する。
var ds = new SampleDataSet();
var row = (SampleDataSet.TableRow)ds.Table.NewRow();
row.ID = 1;
row.NAME = "名前";
row.ADDRESS = null;
row.SetAGENull();
ds.Table.Rows.Add(row);
labelID.Text = row.ID.ToString();
labelName.Text = row.NAME;
// ここでDBNullエラー
labelAddress.Text = row.ADDRESS;
labelAge.Text = row.AGE.ToString();
- Null許容型にする。
DataSetはObject型に元の値を格納しているが、nullはDBNullを使用する点を考慮すれば、拡張メソッドでNullableにすることは簡単にできる。 -
// 拡張メソッド
public static class DataSetExtension
{
public static T? GetValue(this DataRow row, DataColumn column) where T : struct
{
var value = row[column];
if (Convert.IsDBNull(value))
{
return null;
}
else
{
return (T)value;
}
}
public static string GetValueString(this DataRow row, DataColumn column)
{
var value = row[column];
if (Convert.IsDBNull(value))
{
return null;
}
else
{
return (string)value;
}
}
public static void SetValue(this DataRow row, DataColumn column, object value)
{
if (value == null)
{
row[column] = DBNull.Value;
}
else
{
row[column] = value;
}
}
}
```
- 最終的なコード
作成したGetメソッドとSetメソッド使用するように修正した。
var ds = new SampleDataSet();
var row = (SampleDataSet.TableRow)ds.Table.NewRow();
row.ID = 1;
row.NAME = "名前";
row.SetValue(ds.Table.ADDRESSColumn, null);
row.SetValue(ds.Table.AGEColumn, null);
ds.Table.Rows.Add(row);
labelID.Text = row.ID.ToString();
labelName.Text = row.NAME;
// nullが設定される。
labelAddress.Text = row.GetValueString(ds.Table.ADDRESSColumn);
// 空文字が設定される。Nullable型はnullでToStringしても、NullReferenceExceptionは発生しない。
labelAge.Text = row.GetValue<int>(ds.Table.AGEColumn).ToString();
- .Net 3.5以降
DataRow.Field, DataRow.SetField拡張メソッドを使用するだけでよい。
var ds = new SampleDataSet();
var row = (SampleDataSet.TableRow)ds.Table.NewRow();
row.ID = 1;
row.NAME = "名前";
row.SetField<string>(ds.Table.ADDRESSColumn, null);
row.SetField<int?>(ds.Table.AGEColumn, null);
ds.Table.Rows.Add(row);
labelID.Text = row.ID.ToString();
labelName.Text = row.NAME;
labelAddress.Text = row.Field<string>(ds.Table.ADDRESSColumn);
labelAge.Text = row.Field<int?>(ds.Table.AGEColumn).ToString();