[ Team LiB ]
Recipe 2.18 Controlling the Names Used in a Strongly Typed DataSet
Problem
You want to assign your own names to the classes and properties for strongly typed
DataSet classes.
Solution
Use annotations in the XML schema to control the names of classes and properties in
strongly typed DataSet classes.
The sample uses one XSD file:
CategoriesDS_AnnotatedName.xsd
The schema used to generate the strongly typed DataSet. The schema is annotated
so that you can access the collection of rows in the table by using the Categorys
property of the DataSet rather than categories, each row by using the Category
property of the row collection rather than CategoriesRow, and the CategoryName
field by using the Name property of the row rather than CategoryName. The
annotations are marked in bold in the Example 2-23
.
Example 2-23. File: TypedDataSets\CategoriesDS_AnnotatedName.xsd
<?xml version="1.0" standalone="yes" ?>
<xs:schema id="CategoriesDS_AnnotatedName"
targetNamespace=
"
xmlns:mstns="
xmlns="
xmlns:xs="
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:codegen="urn:schemas-microsoft-com:xml-msprop"
attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="CategoriesDS_AnnotatedName" msdata:IsDataSet="true">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="Categories"
codegen:typedName="Category"
codegen:typedPlural="Categorys">
<xs:complexType>
<xs:sequence>
<xs:element
name="CategoryID"
msdata:ReadOnly="true"
msdata:AutoIncrement="true"
type="xs:int" />
<xs:element
name="CategoryName"
type="xs:string"
codegen:typedName="Name" />
<xs:element
name="Description"
type="xs:string"
minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//mstns:Categories" />
<xs:field xpath="mstns:CategoryID" />
</xs:unique>
</xs:element>
</xs:schema>
The sample code creates a strongly typed DataSet based on the Categories table in
Northwind. The user specifies whether the one based on the default or annotated schema
file is used. In either case, data is loaded into the DataSet and the collections of rows and
columns in the DataSet are iterated over to display the data and to demonstrate the effect
of the schema annotations.
The C# code is shown in Example 2-24
.
Example 2-24. File: TypedDataSetNamesForm.cs
// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Text;
using System.Data;
using System.Data.SqlClient;
// Table name constants
private const String CATEGORIES_TABLE = "Categories";
// . . .
StringBuilder result = new StringBuilder( );
// Create the DataAdapter.
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Categories",
ConfigurationSettings.AppSettings["Sql_ConnectString"]);
if (annotatedRadioButton.Checked)
{
// Create the typed DataSet with name annotations.
CategoriesDS_AnnotatedName ds = new CategoriesDS_AnnotatedName( );
// Fill the Categories table within DataSet.
da.Fill(ds, CATEGORIES_TABLE);
result.Append("Annotated Names" + Environment.NewLine +
Environment.NewLine);
// Iterate over the rows collection and display columns.
// Note that the row collection is Categorys
// and that each row is Category.
foreach(CategoriesDS_AnnotatedName.Category row in ds.Categorys)
{
// Note that the CategoryName field is referred to simply as Name.
result.Append(row.CategoryID + "\t" + row.Name + "\t" +
row.Description + Environment.NewLine);
}
}
else
{
// Create the typed DataSet without name annotations.
CategoriesDS ds = new CategoriesDS( );
da.Fill(ds, CATEGORIES_TABLE);
result.Append("Default" + Environment.NewLine + Environment.NewLine);
// Iterate over the rows collection and display columns.
foreach(CategoriesDS.CategoriesRow row in ds.Categories)
{
result.Append(row.CategoryID + "\t" + row.CategoryName + "\t" +
row.Description + Environment.NewLine);
}
}
resultTextBox.Text = result.ToString( );
Discussion
Annotations are modifications to the XSD schema used to generate a strongly typed
DataSet that allows the names of elements in the strongly typed DataSet to be customized
without changing the underlying schema. This allows more meaningful element names to
be used resulting in code that is easier to read, use, and maintain. Table 2-16
lists
available annotations.
Table 2-16. Available annotations
Annotation Description
typedChildren Name of the method that returns objects from a child data relation.
typedName Name of the object.
typedParent Name of the method that returns an object from a parent data relation.
typedPlural Name of the collection of objects.
nullValue
Value or behavior if the underlying value is DBNull. Table 2-17
lists
possible values for this annotation. The default value is _throw.
Table 2-17 describes possible values for the nullValue annotation.
Table 2-17. Values for nullValue annotation
nullValue Description
Replacement
Value
A value having the same type as the element to be returned
_empty
Return String.Empty for a StringReturn an object created from an
empty constructor for other objectsThrow an exception for primitive
types
_null
Return a null reference for objectsThrow an exception for primitive
types
_throw Raise an exception
Table 2-18 lists the different objects in a strongly typed DataSet and the default names
and available annotations for each.
Table 2-18. Default values and available annotations for elements of strongly typed
DataSet objects
Element Default name
Annotatio
n
DataTable TableNameDataTable typedPlural
DataTable
methods
NewTableNameRowAddTableNameRowDeleteTableNa
meRow
typedName
DataRowCollect
ion
TableName
typedPlural
DataRow TableNameRow typedName
DataColumn DataTable.ColumnNameColumnDataRow.ColumnName typedName
Property
PropertyName
typedName
Child accessor GetChildTableNameRows
typedChildr
en
Parent accessor TableNameRow typedParent
DataSet events
TableNameRowChangeEventTableNameRowChangeEv
entHandler
typedName
The use annotations, a reference to the codegen namespace, must be included in the XSD
schema, as shown:
xmlns:codegen="urn:schemas-microsoft-com:xml-msprop"
The codegen namespace allows the names of methods, properties, relations, constraints,
and events in the strongly typed DataSet to be customized.
[ Team LiB ]