DomainContext et Opérations

Cette rubrique décrit la façon dont le client d'une application Services RIA WCF utilise le contexte de domaine pour communiquer avec le service de domaine dans la couche intermédiaire de l'application. Vous n'interagissez pas directement avec les services de domaine depuis le projet client. Au contraire, une classe de contexte de domaine est générée dans le projet client pour chaque service de domaine du projet serveur. Vous appelez des méthodes sur la classe du contexte de domaine qui correspond à la méthode de service de domaine que vous souhaitez utiliser. La classe de contexte de domaine générée dérive de la classe DomainContext. Par défaut, le contexte de domaine est nommé avec un suffixe de Context au lieu du suffixe de Service utilisé pour nommer le service de domaine. Par exemple, un service de domaine nommé HRService possède un contexte de domaine correspondant nommé HRContext. Pour plus d'informations sur la définition des méthodes de service de domaine, consultez Services de domaine.

Le contexte de domaine généré contient trois méthodes de constructeur :

  1. un constructeur par défaut qui intègre l'URI pour communiquer avec le service de domaine via HTTP ;

  2. un constructeur qui vous permet de spécifier un URI alternatif ;

  3. un constructeur qui vous permet de fournir une mise en œuvre personnalisée de DomainClient. Ce constructeur est en général utilisé pour des tests unitaires ou pour le renvoi vers une couche de transport personnalisée.

La classe DomainContext prend en charge les requêtes, les envois et les appels aux opérations de domaine. Pour chaque type d'opération, il existe une classe correspondante qui représente l'opération asynchrone en cours. Ces classes sont LoadOperation, SubmitOperation et InvokeOperation.

Un objet EntitySet est généré dans le contexte de domaine avec des propriétés qui indiquent les opérations autorisées (insertion, mise à jour ou suppression) à partir du client.

Requêtes

La méthode de requête du contexte de domaine a normalement le même nom que celle du service de domaine, auquel s'ajoute un suffixe de Query. Par exemple, une méthode GetCustomersQuery dans le contexte de domaine est générée à partir d'une méthode GetCustomers dans le service de domaine. La méthode de requête du contexte du domaine retourne un objet EntityQuery que vous pouvez utiliser pour appliquer des opérations supplémentaires.

Toutes les requêtes d'un contexte de domaine sont exécutées de façon asynchrone. Pour exécuter la requête, vous transmettez l'objet EntityQuery sous forme de paramètre dans la méthode Load.

Pour plus d'informations, consultez Procédure pas à pas : Récupération et affichage des données d'un service de domaine.

Le code suivant indique comment récupérer les clients du service de domaine. Il filtre les clients dont le numéro de téléphone commence par 583 et les classe par ordre alphabétique en fonction de LastName. Les résultats s'affichent dans un DataGrid.

Partial Public Class MainPage
    Inherits UserControl

    Private _customerContext As New CustomerDomainContext

    Public Sub New()
        InitializeComponent()

        Dim query As EntityQuery(Of Customer)

        query = _
            From c In Me._customerContext.GetCustomersQuery() _
            Where c.Phone.StartsWith("583") _
            Order By c.LastName

        Dim loadOp = Me._customerContext.Load(query)
        CustomerGrid.ItemsSource = loadOp.Entities
    End Sub

End Class
public partial class MainPage : UserControl
{
    private CustomerDomainContext _customerContext = new CustomerDomainContext();

    public MainPage()
    {
        InitializeComponent();
        EntityQuery<Customer> query = 
            from c in _customerContext.GetCustomersQuery()
            where c.Phone.StartsWith("583")
            orderby c.LastName
            select c;
        LoadOperation<Customer> loadOp = this._customerContext.Load(query);
        CustomerGrid.ItemsSource = loadOp.Entities;
    }
}

Modification des données

Quand le service de domaine comprend des méthodes pour la mise à jour, l'insertion et la suppression d'entités, ces méthodes ne sont pas générées dans le contexte de domaine. Vous utiliserez alors la méthode SubmitChanges sur le contexte de domaine. Les opérations adéquates sur le service de domaine seront appelées. Aucun changement n'est apporté à la source de données jusqu'à ce que vous appeliez SubmitChanges. Vous pouvez annuler les modifications en attente en appelant la méthode RejectChanges.

La classe DomainContext fournit également les propriétés HasChanges et EntityContainer pour vous permettre d'évaluer les modifications en attente. L'objet EntityContainer d'un contexte de domaine suit les modifications en attente. Les modifications en attente ne comprennent pas d'appels aux opérations d'appel dans le service de domaine car les opérations d'appel sont exécutées dès lorsqu'elles sont appelées. Lorsque vous appelez SubmitChanges, toutes les modifications en attente sont transmises ensemble au service de domaine.

Vous pouvez ajouter une nouvelle entité en appelant la méthode Add sur l'objet EntitySet ou la méthode AddNew sur l'objet IEditableCollectionView. Lorsque vous ajoutez une entité en appelant la méthode AddNew, cette entité est rendue dans la collection avant que la nouvelle entité ne soit enregistrée dans la source de données.

Pour plus d'informations, consultez Procédure pas à pas : Édition des données d'un service de domaine.

Méthodes de mise à jour personnalisée

Le contexte de domaine contiendra une méthode pour chaque méthode de mise à jour personnalisée sur le service de domaine ayant un modificateur d'accès public et n'étant pas marquée de l'attribut IgnoreAttribute. La méthode générée dans le contexte de domaine contient le même nom que la méthode sur le service de domaine. Dans le projet client, vous appelez la méthode, mais celle-ci n'est pas réellement exécutée tant que SubmitChanges n'est pas appelée. L'objet EntityContainer suit tous les appels à des méthodes de mise à jour personnalisée sous forme de modifications en attente. Lorsque vous appelez SubmitChanges, la méthode est traitée de façon asynchrone.

La même méthode de mise à jour personnalisée est également générée dans le projet client pour l'entité transmise sous forme de paramètre dans la méthode de mise à jour personnalisée. La méthode de mise à jour personnalisée peut donc être appelée via une instance du contexte de domaine ou via une instance de l'entité. Si vous ouvrez le fichier de code généré, vous remarquerez que la méthode générée dans le contexte de domaine appelle simplement la méthode générée dans l'entité. Dans l'un ou l'autre cas, vous devez encore appeler la méthode SubmitChanges sur le contexte de domaine pour l'exécuter.

L'exemple suivant montre comment appeler une méthode de mise à jour personnalisée nommée ResetPassword sur l'entité. OnSubmitCompleted est une méthode de rappel que vous implémentez pour gérer les résultats de l'opération de données.

selectedCustomer.ResetPassword()
customerContext.SubmitChanges(AddressOf OnSubmitCompleted, Nothing)
selectedCustomer.ResetPassword();
customerContext.SubmitChanges(OnSubmitCompleted, null);

Opérations d'appel

Le contexte de domaine contiendra une méthode pour chaque opération d'appel sur le service de domaine. Contrairement aux opérations de domaine, les opérations d'appel s'exécutent immédiatement. Vous n'appelez pas la méthode SubmitChanges. Les opérations d'appel s'exécutent de façon asynchrone. L'opération d'appel retourne un objet InvokeOperation. Vous récupérez la valeur de la propriété Value pour obtenir la valeur retournée par l'opération de service.

Dans la plupart des scénarios, il est préférable d'utiliser des opérations de requête, et non des opérations d'appel, pour charger des données. Les méthodes de requête retournent un seul objet Entity, IQueryable<Entity> ou IEnumerable<Entity>. Les méthodes de requête font partie intégrante du modèle de données pris en charge par DomainService sur la couche intermédiaire et par DomainContext sur le client. L'infrastructure des Services RIA ne génère d'entité dans le projet client que pour les entités retournées par les méthodes de requête dans un objet DomainService.

Les opérations d'appel fournissent un mécanisme hors plage pour le retour des données non-entité et l'exécution d'opérations avec des effets secondaires. Pour plus d'informations sur les effets secondaires, voir la propriété HasSideEffects. Les opérations d'appel ne sont en général pas appropriées pour les méthodes de requête. Même quand une opération d'appel retourne une entité, l'entité n'est générée pour le projet client que si elle est retournée par une méthode de requête.

L'exemple suivant montre comment utiliser une opération d'appel nommée GetLocalTemperature. Dans cet exemple, supposez que la méthode récupère une valeur qui n'est associée à aucune donnée d'entité.

Dim invokeOp As InvokeOperation(Of Integer)
invokeOp = customerContext.GetLocalTemperature(selectedPostalCode, AddressOf OnInvokeCompleted, Nothing)

Private Sub OnInvokeCompleted(ByVal invOp As InvokeOperation(Of Integer))
  If (invOp.HasError) Then
    MessageBox.Show(String.Format("Method Failed: {0}", invOp.Error.Message))
    invOp.MarkErrorAsHandled()
  Else
    result = invOp.Value
  End If
End Sub
InvokeOperation<int> invokeOp = customerContext.GetLocalTemperature(selectedPostalCode, OnInvokeCompleted, null);

private void OnInvokeCompleted(InvokeOperation<int> invOp)
{
  if (invOp.HasError)
  {
    MessageBox.Show(string.Format("Method Failed: {0}", invOp.Error.Message));
    invOp.MarkErrorAsHandled();
  }
  else
  {
    result = invOp.Value;
  }
}

Gestion des erreurs

Quand vous récupérez ou modifiez des données, vous devez décider de la façon de gérer les erreurs que ces opérations peuvent entraîner. Lorsque vous appelez des méthodes sur le contexte de domaine qui récupèrent ou modifient des données, vous incluez des paramètres qui spécifient des mesures de gestion des erreurs. Au moment de charger des données, vous pouvez spécifier d'ignorer les erreurs. Lorsque vous modifiez des données, vous devez gérer l'exception retournée. Pour plus d'informations, consultez Gestion des erreurs sur le client.