Skip to main content

Annotations Reference

The AdoNet.Async typed DataSet source generator supports two families of XML annotations on XSD elements: codegen annotations (from the urn:schemas-microsoft-com:xml-msprop namespace) that control code generation, and msdata annotations (from the urn:schemas-microsoft-com:xml-msdata namespace) that control DataSet schema behavior.

Declare both namespaces on your root xs:schema element:

<xs:schema id="MyDS"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:codegen="urn:schemas-microsoft-com:xml-msprop">

codegen: Annotations

These annotations control naming and null-value behavior in the generated C# code.

codegen:typedName

Applies to: table element (xs:element inside the DataSet's xs:choice)

Overrides the name used for the generated row class. Also affects the names of AddRowAsync, RemoveRowAsync, and NewRow methods.

<xs:element name="Category" codegen:typedName="CategoryEntry">
...
</xs:element>

Default: uses the table element name (e.g., Category).

Effect on generated code:

Without annotationWith codegen:typedName="CategoryEntry"
AsyncCategoryRowAsyncCategoryEntryRow
AddCategoryRowAsync(...)AddCategoryEntryRowAsync(...)
RemoveCategoryRowAsync(...)RemoveCategoryEntryRowAsync(...)
NewCategoryRow()NewCategoryEntryRow()
AsyncCategoryRowChangeEventAsyncCategoryEntryRowChangeEvent

codegen:typedPlural

Applies to: table element

Overrides the name used for the generated table class and the table accessor property on the DataSet.

<xs:element name="Category" codegen:typedPlural="Categories">
...
</xs:element>

Default: uses the table element name (e.g., Category).

Effect on generated code:

Without annotationWith codegen:typedPlural="Categories"
AsyncCategoryDataTableAsyncCategoriesDataTable
ds.Categoryds.Categories

codegen:typedParent

Applies to: xs:keyref element

Overrides the name of the child-to-parent property on the child row class. The generator appends Row to the value.

<xs:keyref name="FK_Category_Product" refer="PK_Category"
codegen:typedParent="Category">
<xs:selector xpath=".//Product" />
<xs:field xpath="CategoryId" />
</xs:keyref>

Default: {ParentTableName}Row (e.g., CategoryRow).

Effect on generated code:

Without annotationWith codegen:typedParent="Category"
product.CategoryRowproduct.CategoryRow (same in this case)
SetCategoryRowAsync(...)SetCategoryRowAsync(...)

This annotation is most useful when a child table has multiple relations to the same parent table, or when the parent table name does not read naturally as a property name.


codegen:typedChildren

Applies to: xs:keyref element

Overrides the name of the parent-to-child method on the parent row class.

<xs:keyref name="FK_Category_Product" refer="PK_Category"
codegen:typedChildren="GetProducts">
<xs:selector xpath=".//Product" />
<xs:field xpath="CategoryId" />
</xs:keyref>

Default: Get{ChildTableName}Rows (e.g., GetProductRows).

Effect on generated code:

Without annotationWith codegen:typedChildren="GetProducts"
category.GetProductRows()category.GetProducts()

codegen:nullValue

Applies to: column element (xs:element inside a table's xs:sequence) that has minOccurs="0"

Controls what happens when the property getter is called on a column whose current value is DBNull. Has no effect on non-nullable columns.

ValueBehaviorGenerated Property
(not set)Throw -- throws StrongTypingExceptionpublic string Email { get { if (IsNull("Email")) throw ...; return ...; } }
_throwSame as not setSame as above
_nullReturnNull -- returns nullpublic string? Email => IsNull("Email") ? null : ...;
_empty or ""ReturnEmpty -- returns "" for strings, default(T) for value typespublic string Email => IsNull("Email") ? "" : ...;
Any other stringReplacementValue -- returns the literalpublic string Email => IsNull("Email") ? "N/A" : ...;

Examples:

<!-- Throw on null (default) -->
<xs:element name="Email" type="xs:string" minOccurs="0" />

<!-- Return null -->
<xs:element name="Description" type="xs:string" minOccurs="0"
codegen:nullValue="_null" />

<!-- Return empty string -->
<xs:element name="Notes" type="xs:string" minOccurs="0"
codegen:nullValue="" />

<!-- Return replacement value -->
<xs:element name="Notes" type="xs:string" minOccurs="0"
codegen:nullValue="N/A" />
warning

The _null behavior changes the property return type to nullable (e.g., string?). The other behaviors keep the return type non-nullable since they always return a value.


msdata: Annotations

These annotations control the schema structure of the underlying DataSet, DataTable, and DataColumn objects.

msdata:IsDataSet

Applies to: root xs:element

Required. Marks the element as the DataSet root. The generator only processes elements with msdata:IsDataSet="true".

<xs:element name="OrdersDS" msdata:IsDataSet="true">
...
</xs:element>

Effect: The element's name becomes the DataSet name (e.g., AsyncOrdersDS). Its child elements become tables.


msdata:PrimaryKey

Applies to: xs:unique or xs:key element

Marks the constraint as a primary key. This sets DataTable.PrimaryKey and enables the FindBy method on the generated table class.

<xs:unique name="PK_Customer" msdata:PrimaryKey="true">
<xs:selector xpath=".//Customer" />
<xs:field xpath="CustomerId" />
</xs:unique>

Effect on generated code:

// FindByCustomerId is generated because PK_Customer is a primary key
AsyncCustomerRow? row = ds.Customer.FindByCustomerId(42);

Without msdata:PrimaryKey="true", the constraint is treated as a unique constraint only, and no FindBy method is generated.


msdata:AutoIncrement

Applies to: column element

Marks the column as auto-incrementing. Auto-increment columns are excluded from the AddRowAsync parameter list.

<xs:element name="OrderId" type="xs:int"
msdata:AutoIncrement="true"
msdata:AutoIncrementSeed="1"
msdata:AutoIncrementStep="1" />

Effect:

  • Sets DataColumn.AutoIncrement = true
  • Sets DataColumn.AutoIncrementSeed and DataColumn.AutoIncrementStep
  • The column is excluded from AddOrderRowAsync parameters
  • A getter property and async setter are still generated

msdata:AutoIncrementSeed

Applies to: column element

The starting value for auto-increment. Defaults to 0.

<xs:element name="OrderId" type="xs:int"
msdata:AutoIncrement="true"
msdata:AutoIncrementSeed="1000" />

msdata:AutoIncrementStep

Applies to: column element

The increment step value. Defaults to 1.

<xs:element name="OrderId" type="xs:int"
msdata:AutoIncrement="true"
msdata:AutoIncrementStep="10" />

msdata:ReadOnly

Applies to: column element

Marks the column as read-only. No async setter method is generated, and the column is excluded from AddRowAsync parameters.

<xs:element name="Discount" type="xs:decimal"
msdata:ReadOnly="true"
msdata:DefaultValue="0" />

Effect on generated code:

  • line.Discount -- property getter is generated (read-only)
  • SetDiscountAsync -- not generated
  • AddSalesOrderLineRowAsync -- Discount is excluded from parameters
  • DataColumn.ReadOnly = true

msdata:Expression

Applies to: column element

Defines a computed column expression. The column becomes read-only: no setter is generated, and the column is excluded from AddRowAsync parameters.

<xs:element name="LineTotal" type="xs:decimal"
msdata:ReadOnly="true"
msdata:Expression="Quantity * UnitPrice" />

Effect on generated code:

// Computed automatically -- no setter exists
decimal total = line.LineTotal; // returns Quantity * UnitPrice

// Expression is set on the DataColumn
ds.SalesOrderLine.LineTotalColumn.Expression; // "Quantity * UnitPrice"
ds.SalesOrderLine.LineTotalColumn.ReadOnly; // true
info

Expression columns should typically also have msdata:ReadOnly="true". While the generator omits setters for expression columns regardless of the ReadOnly flag, setting ReadOnly prevents accidental writes through the untyped DataRow API.


msdata:DefaultValue

Applies to: column element

Sets the default value for the column. When a row is added without explicitly setting this column, the default value is used.

<xs:element name="Price" type="xs:decimal"
msdata:DefaultValue="0" />

Effect:

  • Sets DataColumn.DefaultValue
  • The column can still be set explicitly via the async setter
var row = ds.Product.NewProductRow();
// Price not set -- defaults to 0
await ds.Product.Rows.AddAsync(row);
row.Price; // 0m

msdata:DataType

Applies to: column element

Overrides the CLR type for the column, bypassing the standard XSD-to-CLR type mapping. Useful for types not directly representable in XSD, such as System.Guid.

<xs:element name="Sku" msdata:DataType="System.Guid" minOccurs="0" />

Effect on generated code:

// Property type is Guid, not string
Guid sku = product.Sku;
await product.SetSkuAsync(Guid.NewGuid());

The value must be a fully-qualified CLR type name (e.g., System.Guid, System.TimeSpan, System.Byte[]).


msdata:Ordinal

Applies to: column element

Sets the column's ordinal position within the DataTable. Parsed but does not directly affect code generation -- the column order in the XSD sequence determines property order.

<xs:element name="Name" type="xs:string" msdata:Ordinal="1" />

msdata:Caption

Applies to: column element

Sets DataColumn.Caption, which is a user-friendly label for UI binding.

<xs:element name="CustomerId" type="xs:int" msdata:Caption="Customer ID" />

Effect:

ds.Customer.CustomerIdColumn.Caption;  // "Customer ID"

msdata:MaxLength

Applies to: column element (typically xs:string columns)

Sets DataColumn.MaxLength. Note that this is declared using the standard XSD maxLength attribute, not the msdata: namespace.

<xs:element name="Name" type="xs:string" maxLength="100" />

Effect:

ds.Customer.NameColumn.MaxLength;  // 100

msdata:ConstraintOnly

Applies to: xs:keyref element

When true, creates a ForeignKeyConstraint but does not create a DataRelation. No parent/child navigation methods are generated.

<xs:keyref name="FK_Region_Store" refer="PK_Region"
msdata:ConstraintOnly="true">
<xs:selector xpath=".//Store" />
<xs:field xpath="RegionId" />
</xs:keyref>

Effect:

  • FK constraint is added to the child table with the specified rules
  • No DataRelation is created
  • No Get{ChildTable}Rows() method on the parent row
  • No {ParentTable}Row property on the child row
  • FK column appears as a raw value parameter in AddRowAsync (not a parent row parameter)

See Relations -- Constraint-Only Relations for details.


msdata:IsNested

Applies to: xs:keyref element

Sets DataRelation.Nested = true. This affects how the DataSet is serialized to XML: child rows are nested inside parent elements instead of being flat.

<xs:keyref name="FK_Customer_Order" refer="PK_Customer"
msdata:IsNested="true">
<xs:selector xpath=".//Order" />
<xs:field xpath="CustomerId" />
</xs:keyref>

Effect: Only affects XML serialization behavior. Navigation methods are generated identically.


msdata:UpdateRule

Applies to: xs:keyref element

Sets the ForeignKeyConstraint.UpdateRule. Controls what happens to child rows when the parent's key column is updated.

ValueBehavior
Cascade (default)Child FK values are updated to match
SetNullChild FK values are set to DBNull
SetDefaultChild FK values are set to their default
NoneNo action taken
<xs:keyref name="FK_Customer_Order" refer="PK_Customer"
msdata:UpdateRule="Cascade">
...
</xs:keyref>

msdata:DeleteRule

Applies to: xs:keyref element

Sets the ForeignKeyConstraint.DeleteRule. Controls what happens to child rows when the parent row is deleted.

ValueBehavior
Cascade (default)Child rows are deleted
SetNullChild FK values are set to DBNull
SetDefaultChild FK values are set to their default
NoneNo action taken (may throw if children exist)
<xs:keyref name="FK_Customer_Order" refer="PK_Customer"
msdata:DeleteRule="SetNull">
...
</xs:keyref>

msdata:AcceptRejectRule

Applies to: xs:keyref element

Sets the ForeignKeyConstraint.AcceptRejectRule. Controls what happens to child rows when AcceptChanges or RejectChanges is called on the parent.

ValueBehavior
None (default)No action taken
CascadeAcceptChanges/RejectChanges cascades to children
<xs:keyref name="FK_Customer_Order" refer="PK_Customer"
msdata:AcceptRejectRule="Cascade">
...
</xs:keyref>

msdata:Locale

Applies to: DataSet root element

Sets the DataSet's Locale property for culture-sensitive comparisons.

<xs:element name="OrdersDS" msdata:IsDataSet="true"
msdata:Locale="en-US">
...
</xs:element>

Effect:

var inner = (DataSet)ds;
inner.Locale.Name; // "en-US"

msdata:CaseSensitive

Applies to: DataSet root element

Sets DataSet.CaseSensitive. When true, string comparisons and sorts within the DataSet are case-sensitive.

<xs:element name="AdvancedDS" msdata:IsDataSet="true"
msdata:CaseSensitive="true">
...
</xs:element>

Effect:

var inner = (DataSet)ds;
inner.CaseSensitive; // true

msdata:EnforceConstraints

Applies to: DataSet root element

Sets DataSet.EnforceConstraints. When true (the default), the DataSet validates constraints (unique, foreign key) on every change.

<xs:element name="AdvancedDS" msdata:IsDataSet="true"
msdata:EnforceConstraints="true">
...
</xs:element>

Quick Reference Table

AnnotationApplies ToPurpose
codegen:typedNameTable elementOverride row class name
codegen:typedPluralTable elementOverride table class name and accessor
codegen:typedParentxs:keyrefOverride parent row property name
codegen:typedChildrenxs:keyrefOverride child rows method name
codegen:nullValueColumn elementNull-value read behavior
msdata:IsDataSetRoot elementRequired. Mark as DataSet
msdata:PrimaryKeyxs:unique/xs:keyMark as primary key, enable FindBy
msdata:AutoIncrementColumn elementAuto-increment column
msdata:AutoIncrementSeedColumn elementAuto-increment starting value
msdata:AutoIncrementStepColumn elementAuto-increment step value
msdata:ReadOnlyColumn elementNo setter generated
msdata:ExpressionColumn elementComputed column, no setter generated
msdata:DefaultValueColumn elementColumn default value
msdata:DataTypeColumn elementCLR type override
msdata:OrdinalColumn elementColumn ordinal position
msdata:CaptionColumn elementColumn display caption
maxLengthColumn elementColumn max length (standard XSD attribute)
msdata:ConstraintOnlyxs:keyrefFK constraint without DataRelation
msdata:IsNestedxs:keyrefNested relation for XML serialization
msdata:UpdateRulexs:keyrefFK update rule
msdata:DeleteRulexs:keyrefFK delete rule
msdata:AcceptRejectRulexs:keyrefFK accept/reject rule
msdata:LocaleDataSet rootDataSet locale
msdata:CaseSensitiveDataSet rootCase-sensitive comparisons
msdata:EnforceConstraintsDataSet rootConstraint enforcement