将批注用于类型化 DataSet (摘自MSDN)

  批注使您能够在不修改基础架构的情况下修改类型化 DataSet 中元素的名称。如果修改基础架构中元素的名称,则会使类型化 DataSet 引用不存在于数据源中的对象,并且会丢失对存在于数据源中的对象的引用。

  利用批注,您可以使用更有意义的名称来自定义类型化 DataSet 中对象的名称,从而使代码更易于阅读,类型化 DataSet 更易于为客户端使用,同时保持基础架构不变。例如,Northwind 数据库中 Customers 表的以下架构元素会生成 CustomersRow 这一 DataRow 对象名称和一个名为 CustomersDataRowCollection

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


DataRowCollection 名称 Customers 在客户端代码中是有意义的,但 DataRow 名称 CustomersRow 则会导致误解,因为它是单个对象。此外,在通常情况下,将不使用 Row 标识符来引用该对象,而仅将该对象当作 Customer 对象来引用。解决方案是批注架构并标识 DataRowDataRowCollection 对象的新名称。下面是上一架构的批注版本。

<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>


Customer 的值指定为 typedName 将生成 DataRow 对象名称 Customer。将 Customers 的值指定为 typedPlural 则会保留 DataRowCollection 名称 Customers

下表显示可用的批注。

批注 说明
typedName 对象的名称。
typedPlural 对象集合的名称。
typedParent 对象在父关系中被引用时的名称。
typedChildren 用于从子关系中返回对象的方法的名称。
nullValue 如果基础值为 DBNull,则为值。有关 nullValue 批注的信息,请参见下表。默认为 _throw

下表显示可为 nullValue 批注指定的值。

nullValue 说明
替换值 指定要返回的值。所返回的值必须匹配该元素的类型。例如,使用 nullValue="0" 可为空整数字段返回 0。
_throw 引发异常。这是默认值。
_null 如果遇到基元类型,则返回空引用或引发异常。
_empty 对于字符串返回 String.Empty;否则,返回从空构造函数创建的对象。如果遇到基元类型,则引发异常。

下表显示类型化 DataSet 中对象的默认值以及可用的批注。

对象/方法/事件 默认值 批注
DataTable TableNameDataTable typedPlural
DataTable 方法 NewTableNameRow

AddTableNameRow

DeleteTableNameRow

typedName
DataRowCollection TableName typedPlural
DataRow TableNameRow typedName
DataColumn DataTable.ColumnNameColumn

DataRow.ColumnName

typedName
Property PropertyName typedName
Child Accessor GetChildTableNameRows typedChildren
Parent Accessor TableNameRow typedParent
DataSet 事件 TableNameRowChangeEvent

TableNameRowChangeEventHandler

typedName

若要使用类型化 DataSet 批注,则必须在 XML 架构定义语言 (XSD) 架构中包含以下 xmlns 引用。

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


下面是一个批注架构示例,它公开 Northwind 数据库的 Customers 表并包含与 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="OrderDate" codegen:typedName="OrderDate" 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。它使用一个 DataAdapter 填充 Customers 表,并使用另一个 DataAdapter 填充 Orders 表。强类型 DataSet 定义 DataRelations

[Visual Basic]
Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;" & _
                                                   "Initial Catalog=northwind")
Dim custDA As SqlDataAdapter = New SqlDataAdapter("SELECT CustomerID, CompanyName, Phone FROM Customers", &
                                                  nwindConn)
Dim orderDA As SqlDataAdapter = New SqlDataAdapter("SELECT OrderID, CustomerID, EmployeeID, OrderDate FROM Orders", &
                                                   nwindConn)
' Populate a strongly typed DataSet.
nwindConn.Open()
Dim custDS As CustomerDataSet = New CustomerDataSet()
custDA.Fill(custDS, "Customers")
orderDA.Fill(custDS, "Orders")
nwindConn.Close()
' Add a strongly typed event.
AddHandler custDS.Customers.CustomerChanged, &
           New CustomerDataSet.CustomerChangeEventHandler(AddressOf OnCustomerChanged)
' Add a strongly typed DataRow.
Dim newCust As CustomerDataSet.Customer = custDS.Customers.NewCustomer()
newCust.CustomerID = "NEW01"
newCust.CompanyName = "My New Company"
custDS.Customers.AddCustomer(newCust)
' Navigate the child relation.
Dim customer As CustomerDataSet.Customer
Dim order As CustomerDataSet.Order
For Each customer In custDS.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
[C#]
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");
SqlDataAdapter custDA = new SqlDataAdapter("SELECT CustomerID, CompanyName, Phone FROM Customers", nwindConn);
SqlDataAdapter orderDA = new SqlDataAdapter("SELECT OrderID, CustomerID, EmployeeID, OrderDate FROM Orders", nwindConn);
// Populate a strongly typed DataSet.
nwindConn.Open();
CustomerDataSet custDS = new CustomerDataSet();
custDA.Fill(custDS, "Customers");
orderDA.Fill(custDS, "Orders");
nwindConn.Close();
// Add a strongly typed event.
custDS.Customers.CustomerChanged += new 
  CustomerDataSet.CustomerChangeEventHandler(OnCustomerChanged);
// Add a strongly typed DataRow.
CustomerDataSet.Customer newCust = custDS.Customers.NewCustomer();
newCust.CustomerID = "NEW01";
newCust.CompanyName = "My New Company";
custDS.Customers.AddCustomer(newCust);
// Navigate the child relation.
foreach(CustomerDataSet.Customer customer in custDS.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)
{
}


posted @ 2006-03-13 10:23  大洋  阅读(473)  评论(0编辑  收藏  举报