DataColumnクラス

DataTableの列のスキーマ (schema) を表します。

プロパティ

プロパティ 内容 既定値
DataTable Table 列が属しているDataTable  
string ColumnName 列の名前。これが既定の空文字列のままDataColumnCollectionに追加されると、既定の名前であるColumn1、Column2…が設定される  
string Caption 列の見出し (キャプション)。これが設定されていないならば、ColumnNameの値が返される  
bool AllowDBNull trueならば、nullを許可する true
bool Unique trueならば、唯一でなければならない false
bool ReadOnly trueならば、読み取り専用

Tableに追加する前に値を設定しなければならない。追加後に設定すると、ReadOnlyExceptionが投げられる。一方で追加前か除去後のDetachedの状態ならば、値を変更できる

false
bool AutoIncrement trueならば、テーブルに行を追加したとき、またはDataTable.NewRow()で行を作成したときに、増加した値を自動的に設定する false
Type DataType 列に格納されるデータの型。これはDataView.SortやDataView.RowFilterの基準となる String
object DefaultValue 新しい行を作成したときの、列の既定値  
DataSetDateTime DateTimeMode 列のDateTimeMode UnspecifiedLocal
MappingType ColumnMapping 列のMappingType Element
string Expression 式。行のフィルタ、演算または集合関数の結果の列への出力に用いる ""
       
Properties - DataColumn Class (System.Data) | Microsoft Learn

ColumnName

RowFilterではParentChildを親や子テーブルを指定するための接頭辞として用いているため、これらを列の名前とすることは避けます。

DataTable table = new DataTable();
table.Columns.Add("parent");

table.Select("parent = 1");  // SyntaxErrorException「Dot が必要ですが、位置 8 の実際のトークンは BinaryOp です。」

Unique

DataTable.CaseSensitiveがfalseならば、大文字/小文字の区別なく唯一でなければなりません。つまり"a"と"A"は区別されないため、"a"がある列に"A"は追加できません。またLocaleの設定によっては、"あ"と"ア"も区別されません。

DataTable table = new DataTable();
table.CaseSensitive = false;
table.Locale = new System.Globalization.CultureInfo("ja-JP");

DataColumn column = table.Columns.Add("col1");
column.Unique = true;

table.Rows.Add("a");
table.Rows.Add("A"); // ConstraintException「列 'col1' は一意であるように制約されています。値 'A' は既に存在します。」

table.Rows.Add("あ");
table.Rows.Add("ア"); // ConstraintException「列 'col1' は一意であるように制約されています。値 'ア' は既に存在します。」

Uniqueをtrueにすると、テーブルの制約にUniqueConstraintが追加されます。一方でUniqueConstraintを追加すると、そこで指定した列のUniqueがtrueになります。

DataRowStateがDeletedとなっていれば、その行の値と重複していても追加できます。ただし追加後にその行の削除を取り消そうとするとConstraintExceptionが投げられます。

DataTable table = new DataTable();
DataColumn column = table.Columns.Add();
column.Unique = true;

DataRow row = table.Rows.Add("a");
row.AcceptChanges();
row.Delete();
DataRowState state = row.RowState; // Deleted

table.Rows.Add("a");

row.RejectChanges(); // ConstraintException

AutoIncrement

AutoIncrementをtrueとした列に値を自動的に設定させるには、値を指定しないかnullを指定します。DataColumn.AutoIncrement Property (System.Data) | Microsoft Learn

DataTable table = new DataTable();
DataColumn column = table.Columns.Add();

string type1 = column.DataType.FullName; // "System.String"
column.AutoIncrement = true;
string type2 = column.DataType.FullName; // "System.Int32" … trueに設定するときDataTypeがInt16、Int32、Int64以外ならば、Int32に変更される

column.AutoIncrementSeed = 10; // AutoIncrementで設定するときの初期値。既定は0
column.AutoIncrementStep = 2;  // AutoIncrementで加算する値。既定は1


DataRow row1 = table.Rows.Add();   // 10 … row1.ItemArray[0]の値
DataRow row2 = table.Rows.Add();   // 12
DataRow row3 = table.Rows.Add(20); // 20 … 任意の値を指定することも可能
DataRow row4 = table.Rows.Add();   // 22 … 最大値に対して加算された値になる

row2.Delete(); // 途中の行を削除
DataRow row5 = table.Rows.Add(); // 24

row5.Delete(); // 末尾の行を削除。現在の最大値は22となる
DataRow row6 = table.Rows.Add(); // 26 … 現在の最大値とは無関係に、これまでの最大値となる

row6[column] = 30; // 現在の最大値を書き換える
DataRow row7 = table.Rows.Add(); // 32 … 最大値に対して加算された値になる

DataRow row8 = table.NewRow(); // 34 … NewRow()で作成した時点で値が設定される
table.Rows.Add(row8);

値の上限

AutoIncrementをtrueとする列のDataTypeがInt16、Int32、Int64以外ならばInt32に設定されるため、値がInt32.MaxValueを超えるとオーバーフローします。

DataTable table = new DataTable();

DataColumn column = table.Columns.Add();
column.AutoIncrement = true;
column.AutoIncrementSeed = int.MaxValue;

table.Rows.Add();
table.Rows.Add(); // OverflowException「Int32 型の値が大きすぎるか、または小さすぎます。」

ColumnMapping

下表の値を指定できます。

列挙子 列の割り当て先
Element 1 XML要素
Attribute 2 XML属性
SimpleContent 3 System.Xml.XmlTextノード
Hidden 4 内部構造
MappingType Enum (System.Data) | Microsoft Learn

ColumnMappingを変更すると、

DataTable table1 = new DataTable("sample1");

table1.Columns.Add("Element").ColumnMapping = MappingType.Element;
table1.Columns.Add("Attribute").ColumnMapping = MappingType.Attribute;
//table1.Columns.Add("SimpleContent").ColumnMapping = MappingType.SimpleContent; // ArgumentException「SimpleContent 列を、要素列または入れ子にされたリレーションシップを含むテーブルには追加できません。」
table1.Columns.Add("Hidden").ColumnMapping = MappingType.Hidden;

table1.Rows.Add("ELEMENT", "ATTRIBUTE", "HIDDEN");

table1.WriteXml("sample1.xml");
table1.WriteXmlSchema("sample1.xsd");

DataTable.WriteXml()では次のように、

<?xml version="1.0" standalone="yes"?>
<DocumentElement>
  <sample1 Attribute="ATTRIBUTE">
    <Element>ELEMENT</Element>
  </sample1>
</DocumentElement>

DataTable.WriteXmlSchema()では次のように出力されます。

<?xml version="1.0" standalone="yes"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="sample1" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="sample1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Element" type="xs:string" minOccurs="0" msdata:Ordinal="0" />
            </xs:sequence>
            <xs:attribute name="Attribute" type="xs:string" />
            <xs:attribute name="Hidden" type="xs:string" use="prohibited" />
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

MappingType.SimpleContent

SimpleContentは単独で指定します。

DataTable table2 = new DataTable("sample2");

table2.Columns.Add("SimpleContent").ColumnMapping = MappingType.SimpleContent;
//table2.Columns.Add("SimpleContent2").ColumnMapping = MappingType.SimpleContent; // ArgumentException「入れ子にされたリレーションシップまたは要素列を、SimpleContent 列を含むテーブルに追加することはできません。」

table2.Rows.Add("SIMPLECONTENT");

table2.WriteXml("sample2.xml");
table2.WriteXmlSchema("sample2.xsd");

DataTable.WriteXml()の出力

<?xml version="1.0" standalone="yes"?>
<DocumentElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <sample2>SIMPLECONTENT</sample2>
</DocumentElement>

DataTable.WriteXmlSchema()の出力

<?xml version="1.0" standalone="yes"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="sample2" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="sample2" nillable="true">
          <xs:complexType>
            <xs:simpleContent msdata:ColumnName="SimpleContent" msdata:Ordinal="0">
              <xs:extension base="xs:string">
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

MappingType.Attribute

ColumnMappingをMappingType.Attributeとしたとき、DataColumn.DataTypeの型によってはWriteXml()などで出力するときに「'***' 型の DataColumn は complexType です。複合型の値を Attribute としてシリアル化することはできません (DataColumn with type '***' is a complexType. Can not serialize value of a complex type as Attribute.)」としてArgumentExceptionが投げられることがあります。その場合には、MappingType.Attribute以外を指定します。

Expression

RowFilterと同様の式を指定することで、値に演算結果を設定できます。DataColumn.Expression Property (System.Data) | Microsoft Learn

DataTable table = new DataTable();
table.Columns.Add("A", typeof(int));
table.Columns.Add("B", typeof(int));

DataColumn column = table.Columns.Add("C", typeof(int));
column.Expression = "A + B";

DataRow row = table.Rows.Add(1, 2);
int r = row.Field<int>(column); // 3
Microsoft Learnから検索