LoginSignup
4
2

More than 5 years have passed since last update.

型付きDataSetのDataRowからNull許容で値を取得する。(.Net)

Last updated at Posted at 2017-02-12

型付データセット

.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<T>(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();

目次

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2