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 | 式。行のフィルタ、演算または集合関数の結果の列への出力に用いる | "" |
RowFilterではParentとChildを親や子テーブルを指定するための接頭辞として用いているため、これらを列の名前とすることは避けます。
DataTable table = new DataTable();
table.Columns.Add("parent");
table.Select("parent = 1"); // SyntaxErrorException「Dot が必要ですが、位置 8 の実際のトークンは BinaryOp です。」
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を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 型の値が大きすぎるか、または小さすぎます。」
下表の値を指定できます。
列挙子 | 値 | 列の割り当て先 |
---|---|---|
Element | 1 | XML要素 |
Attribute | 2 | XML属性 |
SimpleContent | 3 | System.Xml.XmlTextノード |
Hidden | 4 | 内部構造 |
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>
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>
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以外を指定します。
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