Аннотирование типизированных наборов данных

Заметки позволяют изменять имена элементов в типизированной DataSet схеме без изменения базовой схемы. Изменение имен элементов в базовой схеме приведет к тому, что типизированная DataSet ссылка будет указывать на объекты, которые не существуют в источнике данных, а также к утрате ссылок на объекты, которые существуют в источнике данных.

С помощью аннотаций можно настраивать имена объектов в вашем типизированном DataSet с более значимыми названиями, что делает код более читаемым и упрощает использование типизированного DataSet для клиентов, при этом оставляя базовую схему в неизменном виде. Например, следующий элемент схемы для таблицы Customers базы данных Northwind приведет к имени объекта DataRow и имени CustomersRow «Клиенты».

<xs:element name="Customers">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="CustomerID" type="xs:string" minOccurs="0" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

Имя DataRowCollection имеет смысл в клиентском коде, но имя CustomersDataRow вводит в заблуждение, так как это единый объект. Кроме того, в распространенных сценариях объект будет называться без идентификатора Row и вместо этого будет просто называться Customer объектом. Решение заключается в том, чтобы идентифицировать схему и определить новые имена для DataRow объектов и DataRowCollection объектов. Ниже приведена аннотированная версия предыдущей схемы.

<xs:element name="Customers" codegen:typedName="Customer" codegen:typedPlural="Customers">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="CustomerID" type="xs:string" minOccurs="0" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

Указание typedName значения Customer задаст имя объекта DataRow. Указание значения typedPlural для Customers сохраняет имя DataRowCollectionКлиентов.

В следующей таблице показаны заметки, доступные для использования.

Аннотация Описание
typedName Имя объекта.
typedPlural Имя коллекции объектов.
typedParent Имя объекта в контексте отношения родитель.
typedChildren Имя метода, возвращающего объекты из дочернего отношения.
NULLValue Значение, если базовое значение — DBNull. Посмотрите следующую таблицу аннотаций nullValue. Значение по умолчанию — _throw.

В следующей таблице показаны значения, которые можно указать для заметки nullValue .

Значение nullValue Описание
Восстановительная стоимость Укажите возвращаемое значение. Возвращаемое значение должно соответствовать типу элемента. Например, используйте nullValue="0" для возврата 0 для полей целочисленного значения NULL.
_выбросить Создание исключения. Это значение по умолчанию.
_null Возвращает ссылку null или создает исключение, если обнаружен примитивный тип.
_пустой Для строк возвращается String.Empty, в противном случае возвращает объект, созданный из пустого конструктора. Если встречается примитивный тип, выбросьте исключение.

В следующей таблице показаны значения по умолчанию для объектов в типизированных DataSet и доступные аннотации.

Объект/Метод/Событие По умолчанию Аннотация
DataTable ИмяТаблицыТаблицаДанных typedPlural
DataTable Методика NewTableNameRow

ДобавитьИмяСтрокиТаблицы

DeleteTableNameRow
введенноеИмя
DataRowCollection ИмяТаблицы typedPlural
DataRow ИмяТаблицыСтрока введенноеИмя
DataColumn DataTable.ColumnNameColumn

DataRow.ColumnName
введенноеИмя
Свойство ИмяСвойства введенноеИмя
Дочерний Акцессор GetChildTableNameRows типизированныеДети
Родительский Аксессор ИмяТаблицыСтрока типизированный родитель
Набор данных События TableNameRowChangeEvent

TableNameRowChangeEventHandler
введенноеИмя

Чтобы использовать типизированные DataSet заметки, необходимо включить следующую xmlns ссылку в схему языка определения схемы XML (XSD). Чтобы создать xsd из таблиц базы данных, см. WriteXmlSchema или раздел «Работа с наборами данных» в Visual Studio.

xmlns:codegen="urn:schemas-microsoft-com:xml-msprop"

Ниже приведен пример аннотированной схемы, которая представляет таблицу Customers базы данных Northwind с включенной связью к таблице Orders.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="CustomerDataSet"
      xmlns:codegen="urn:schemas-microsoft-com:xml-msprop"
      xmlns=""
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="CustomerDataSet" msdata:IsDataSet="true">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="Customers" codegen:typedName="Customer" codegen:typedPlural="Customers">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="CustomerID"
codegen:typedName="CustomerID" type="xs:string" minOccurs="0" />
              <xs:element name="CompanyName"
codegen:typedName="CompanyName" type="xs:string" minOccurs="0" />
              <xs:element name="Phone" codegen:typedName="Phone" codegen:nullValue="" type="xs:string" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="Orders" codegen:typedName="Order" codegen:typedPlural="Orders">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="OrderID" codegen:typedName="OrderID"
type="xs:int" minOccurs="0" />
              <xs:element name="CustomerID"
codegen:typedName="CustomerID"                  codegen:nullValue="" type="xs:string" minOccurs="0" />
              <xs:element name="EmployeeID"
codegen:typedName="EmployeeID" codegen:nullValue="0"
type="xs:int" minOccurs="0" />
              <xs:element name="OrderAdapter"
codegen:typedName="OrderAdapter" codegen:nullValue="1980-01-01T00:00:00"
type="xs:dateTime" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
    <xs:unique name="Constraint1">
      <xs:selector xpath=".//Customers" />
      <xs:field xpath="CustomerID" />
    </xs:unique>
    <xs:keyref name="CustOrders" refer="Constraint1"
codegen:typedParent="Customer" codegen:typedChildren="GetOrders">
      <xs:selector xpath=".//Orders" />
      <xs:field xpath="CustomerID" />
    </xs:keyref>
  </xs:element>
</xs:schema>

В следующем примере кода используется строго типизированный DataSet объект, созданный из примера схемы. Он использует один SqlDataAdapter для заполнения таблицы и другой Customers для заполнения SqlDataAdapterOrders таблицы. Строго типизированный DataSet определяет DataRelations.

' Assumes a valid SqlConnection object named connection.
Dim customerAdapter As SqlDataAdapter = New SqlDataAdapter( _
    "SELECT CustomerID, CompanyName, Phone FROM Customers", &
    connection)
Dim orderAdapter As SqlDataAdapter = New SqlDataAdapter( _
    "SELECT OrderID, CustomerID, EmployeeID, OrderAdapter FROM Orders", &
    connection)

' Populate a strongly typed DataSet.
connection.Open()
Dim customers As CustomerDataSet = New CustomerDataSet()
customerAdapter.Fill(customers, "Customers")
orderAdapter.Fill(customers, "Orders")
connection.Close()

' Add a strongly typed event.
AddHandler customers.Customers.CustomerChanged, &
    New CustomerDataSet.CustomerChangeEventHandler( _
    AddressOf OnCustomerChanged)

' Add a strongly typed DataRow.
Dim newCustomer As CustomerDataSet.Customer = _
    customers.Customers.NewCustomer()
newCustomer.CustomerID = "NEW01"
newCustomer.CompanyName = "My New Company"
customers.Customers.AddCustomer(newCustomer)

' Navigate the child relation.
Dim customer As CustomerDataSet.Customer
Dim order As CustomerDataSet.Order

For Each customer In customers.Customers
  Console.WriteLine(customer.CustomerID)
  For Each order In customer.GetOrders()
    Console.WriteLine(vbTab & order.OrderID)
  Next
Next

Private Shared Sub OnCustomerChanged( _
    sender As Object, e As CustomerDataSet.CustomerChangeEvent)

End Sub
// Assumes a valid SqlConnection object named connection.
SqlDataAdapter customerAdapter = new SqlDataAdapter(
    "SELECT CustomerID, CompanyName, Phone FROM Customers",
    connection);
SqlDataAdapter orderAdapter = new SqlDataAdapter(
    "SELECT OrderID, CustomerID, EmployeeID, OrderAdapter FROM Orders",
    connection);

// Populate a strongly typed DataSet.
connection.Open();
CustomerDataSet customers = new CustomerDataSet();
customerAdapter.Fill(customers, "Customers");
orderAdapter.Fill(customers, "Orders");
connection.Close();

// Add a strongly typed event.
customers.Customers.CustomerChanged += new
  CustomerDataSet.CustomerChangeEventHandler(OnCustomerChanged);

// Add a strongly typed DataRow.
CustomerDataSet.Customer newCustomer =
    customers.Customers.NewCustomer();
newCustomer.CustomerID = "NEW01";
newCustomer.CompanyName = "My New Company";
customers.Customers.AddCustomer(newCustomer);

// Navigate the child relation.
foreach(CustomerDataSet.Customer customer in customers.Customers)
{
  Console.WriteLine(customer.CustomerID);
  foreach(CustomerDataSet.Order order in customer.GetOrders())
    Console.WriteLine("\t" + order.OrderID);
}

protected static void OnCustomerChanged(object sender, CustomerDataSet.CustomerChangeEvent e)
    {

    }

См. также