Создание примечаний к типизированным наборам данных

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

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

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

Имя DataRowCollection клиентов имеет смысл в клиентском коде, но имя DataRow клиентов вводит в заблуждение, так как это один объект. Кроме того, в распространенных сценариях объект будет называться без идентификатора строки и вместо этого будет просто называться объектом 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 клиента приведет к тому, что имя объекта DataRow клиента. Указание значения typedPlural для клиентов сохраняет имя DataRowCollection клиентов.

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

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

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

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

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

Объект/Метод/Событие По умолчанию. Номер
Datatable TableNameDataTable typedPlural
Методы DataTable NewTableNameRow

AddTableNameRow

DeleteTableNameRow
typedName
DataRowCollection TableName typedPlural
Datarow TableNameRow typedName
DataColumn DataTable.ColumnNameColumn

DataRow.ColumnName
typedName
Свойство PropertyName typedName
Дочерний метод доступа GetChildTableNameRows typedChildren
Родительский метод доступа TableNameRow typedParent
События набора данных TableNameRowChangeEvent

TableNameRowChangeEventHandler
typedName

Чтобы использовать типизированные заметки 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>  

В следующем примере кода используется строго типизированный набор данных, созданный из примера схемы. Он использует одно SqlDataAdapter для заполнения таблицы "Клиенты" и другой SqlDataAdapter для заполнения таблицы "Заказы". Строго типизированный набор данных определяет 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)  
    {  
  
    }  

См. также