Share via


Annotation de DataSet typés

Les annotations vous permettent de modifier le nom des éléments de votre objet DataSet typé sans pour autant modifier le schéma sous-jacent. Si vous modifiez les noms des éléments de votre schéma sous-jacent, le DataSet typé fait référence à des objets qui n’existent pas dans la source de données. De plus, cela entraîne la perte de la référence aux objets qui existent réellement dans la source de données.

Si vous utilisez des annotations, vous pouvez personnaliser les noms des objets de votre DataSet typé avec des noms plus significatifs, ce qui rend le code plus lisible et votre DataSet typé plus facile à utiliser par les clients, tout en laissant le schéma sous-jacent intact. Par exemple, l’élément de schéma suivant pour la table Customers de la base de données Northwind donne un objet DataRow nommé CustomersRow, et un DataRowCollection nommé Customers.

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

Le nom Customers pour DataRowCollection est significatif dans le code client, alors que le nom CustomersRow pour DataRow est trompeur, car il s’agit d’un seul objet. De plus, dans les scénarios usuels, l’objet est référencé sans l’identificateur Row. Il est simplement référencé à la place en tant qu’objet Customer. La solution consiste à annoter le schéma et à identifier les nouveaux noms pour les objets DataRow et DataRowCollection. Voici une version annotée du précédent schéma.

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

En affectant à typedName la valeur Customer, vous obtenez un objet DataRow nommé Customer. En affectant à typedPlural la valeur Customers, vous conservez le nom Customers pour DataRowCollection.

Le tableau suivant présente les différentes annotations disponibles.

Annotation Description
typedName Nom de l'objet.
typedPlural Nom d’une collection d’objets.
typedParent Nom de l'objet lorsqu'il y est fait référence dans une relation parente.
typedChildren Nom de la méthode permettant de retourner des objets d'une relation enfant.
nullValue Valeur à utiliser si la valeur sous-jacente est DBNull. Consultez le tableau suivant pour les annotations nullValue. La valeur par défaut est _throw.

Le tableau suivant montre les valeurs qui peuvent être spécifiées pour l’annotation nullValue.

Valeur nullValue Description
Valeur de remplacement Spécifier une valeur à retourner. La valeur retournée doit correspondre au type de l'élément. Par exemple, utilisez nullValue="0" pour retourner 0 pour les champs de type null integer (entier nul).
_throw Levée d'une exception. Il s’agit de la valeur par défaut.
_null Retourner une référence null ou lever une exception si un type primitif est rencontré.
_empty Pour les chaînes, retourne String.Empty. Sinon, retourne un objet créé à partir d’un constructeur vide. Si un type primitif est rencontré, lever une exception.

Le tableau suivant montre les valeurs par défaut des objets d’un DataSet typé ainsi que les annotations disponibles.

Objet/méthode/événement Default Annotation
DataTable TableNameDataTable typedPlural
Méthodes de DataTable NewTableNameRow

AddTableNameRow

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

DataRow.ColumnName
typedName
Propriété PropertyName typedName
Accesseur Child GetChildTableNameRows typedChildren
Accesseur Parent TableNameRow typedParent
Événements de DataSet TableNameRowChangeEvent

TableNameRowChangeEventHandler
typedName

Pour utiliser des annotations de DataSet typées, vous devez inclure la référence xmlns suivante dans votre schéma XSD (langage de définition de schéma XML). Pour créer un XSD à partir de tables de base de données, consultez WriteXmlSchema ou Utilisation de jeux de données dans Visual Studio.

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

Vous trouverez ci-dessous un exemple de schéma annoté exposant la table Customers de la base de données Northwind, qui comporte une relation avec la table 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>  

L’exemple de code suivant utilise un DataSet fortement typé, créé à partir de l’exemple de schéma. Il utilise un SqlDataAdapter pour remplir la table Customers, et un autre SqlDataAdapter pour remplir la table Orders. Le DataSet fortement typé définit 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)  
    {  
  
    }  

Voir aussi