Compartilhar via


Anotando DataSets tipados

As anotações permitem que você modifique os nomes dos elementos em seu tipo DataSet sem modificar o esquema subjacente. Modificar os nomes dos elementos em seu esquema subjacente faria com que os tipos DataSet se referissem a objetos que não existem na fonte de dados, além de perder uma referência aos objetos que existem na fonte de dados.

Usando anotações, você pode personalizar os nomes de objetos em seus tipos DataSet com nomes mais significativos, tornando o código mais legível e seu tipo DataSet mais fácil de usar para os clientes, deixando o esquema subjacente intacto. Por exemplo, o seguinte elemento de esquema para a tabela Customers do banco de dados Northwind resultaria em um objeto de nome CustomersRow e um DataRowCollection nomeado Clientes.

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

Um nome de DataRowCollection é significativo no código do cliente Customers, mas um nome de DataRow é enganoso porque é um único objeto. Além disso, em cenários comuns, o objeto seria referenciado sem o Row identificador e, em vez disso, seria simplesmente chamado de Customer objeto. A solução é anotar o esquema e identificar novos nomes para os objetos DataRow e DataRowCollection. A seguir está a versão anotada do esquema anterior.

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

Especificar um valor de typedNameCustomer resultará em um nome de objeto DataRowCliente. Especificar um typedPlural valor de Customers preserva o DataRowCollection nome dos Clientes.

A tabela a seguir mostra as anotações disponíveis para uso.

Anotação Descrição
typedName Nome do objeto.
typedPlural Nome de uma coleção de objetos.
typedParent Nome do objeto quando chamado em uma relação de pai.
typedChildren Nome do método para retornar objetos de uma relação filho.
nullValue Valor quando o valor subjacente é DBNull. Consulte a tabela a seguir para nullValue obter anotações. O padrão é _throw.

A tabela a seguir mostra os valores que podem ser especificados para a nullValue anotação.

Valor nullValue Descrição
Valor de substituição Especifique um valor a ser retornado. O valor retornado deve corresponder ao tipo do elemento. Por exemplo, use nullValue="0" para retornar 0 para campos inteiros nulos.
_jogar Lance uma exceção. Esse é o padrão.
_zero Retorne uma referência nula ou gere uma exceção se um tipo primitivo for encontrado.
_vazio Para cadeias de caracteres, retorne String.Empty, caso contrário, retorne um objeto criado a partir de um construtor vazio. Se um tipo primitivo for encontrado, gera uma exceção.

A tabela a seguir mostra valores padrão para objetos de um tipo DataSet e as anotações disponíveis.

Objeto/método/evento Padrão Anotação
DataTable TableNameDataTable typedPlural
DataTable Métodos NewTableNameRow

AddTableNameRow

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

DataRow.ColumnName
typedName
Propriedade Nome da Propriedade typedName
Acessador Child GetChildTableNameRows typedChildren
Acessador Parent TableNameRow typedParent
Dataset Eventos TableNameRowChangeEvent

TableNameRowChangeEventHandler
typedName

Para usar anotações digitadas DataSet, você deve incluir a seguinte referência xmlns em seu esquema de Definição de Esquema XML (XSD). Para criar um xsd a partir de tabelas de banco de dados, consulte WriteXmlSchema ou trabalhando com conjuntos de dados no Visual Studio.

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

Veja a seguir um esquema anotado de exemplo que expõe a Customers tabela do banco de Northwind dados com uma relação com a Orders tabela incluída.

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

O exemplo de código a seguir usa um DataSet de tipagem forte criado a partir do esquema de amostra. Ele usa um SqlDataAdapter para preencher a Customers tabela e outro SqlDataAdapter para preencher a Orders tabela. O fortemente tipado DataSet define 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)
    {

    }

Consulte também