Personnalisation du comportement de la commande de suppressionCustomizing Deletion Behavior

La suppression d'un élément provoque généralement aussi la suppression des éléments associés.Deleting an element usually causes related elements to be deleted also. Toutes les relations qui y sont connectées et tous les éléments enfants sont supprimés.All relationships connected to it, and any child elements are deleted. Ce comportement est nommé suppression de la propagation.This behavior is named delete propagation. Vous pouvez personnaliser la propagation de la suppression, par exemple pour que des éléments associés supplémentaires soient supprimés.You can customize delete propagation, for example to arrange that additional related elements are deleted. En écrivant du code de programme, vous pouvez faire en sorte que la propagation de la suppression dépende de l'état du modèle.By writing program code, you can make delete propagation depend on the state of the model. Vous pouvez aussi provoquer d'autres modifications en réponse à une suppression.You can also cause other changes to occur in response to a deletion.

Cette rubrique comporte les sections suivantes :This topic includes the following sections:

Comportement de suppression par défautDefault Deletion Behavior

Par défaut, les règles suivantes régissent la propagation de la suppression :By default, the following rules govern delete propagation:

  • Si un élément est supprimé, tous les éléments incorporés sont également supprimés.If an element is deleted, all embedded elements are also deleted. Les éléments incorporés sont ceux qui sont les cibles de relations d'incorporation pour lesquelles cet élément est la source.The embedded elements are those that are the targets of embedding relationships for which this element is the source. Par exemple, s’il existe une relation d’incorporation de Album à chanson, puis lorsqu’un Album spécifique est supprimé, tous les morceaux seront également supprimés.For example, if there is an embedding relationship from Album to Song, then when a particular Album is deleted, all its Songs will also be deleted.

    En revanche, la suppression d'un morceau ne supprime pas l'album.By contrast, deleting a song does not delete the album.

  • Par défaut, la suppression ne se propage pas le long des relations de référence.By default, deletion does not propagate along reference relationships. S’il existe une relation de référence ArtistPlaysOnAlbum de Album à artiste, suppression d’un album ne supprime pas les artiste connexe et suppression d’un artiste n’est pas supprimer un album.If there is a reference relationship ArtistPlaysOnAlbum from Album to Artist, deleting an album does not delete any related artist, and deleting an artist does not delete any album.

    Toutefois, la suppression se propage le long de certaines relations intégrées.However, deletion does propagate along some built-in relationships. Par exemple, quand un élément de modèle est supprimé, sa forme sur le diagramme est également supprimée.For example, when a model element is deleted, its shape on the diagram is also deleted. L'élément et la forme sont liés par la relation de référence PresentationViewsSubject.The element and shape are related by the PresentationViewsSubject reference relationship.

  • Chaque relation qui est connectée à l'élément, au rôle source ou cible, est supprimée.Every relationship that is connected to the element, either at the source or target role, is deleted. La propriété de rôle de l'élément au niveau du rôle opposé ne contient plus l'élément supprimé.The role property of the element at the opposite role no longer contains the deleted element.

Définition de l’option de propager la suppression d’un rôleSetting the Propagate Delete option of a role

Vous pouvez faire en sorte que la suppression soit propagée le long d'une relation de référence ou d'un enfant incorporé vers son parent.You can cause deletion to propagate along a reference relationship, or from an embedded child to its parent.

Pour définir la propagation de suppressionTo set delete propagation

  1. Dans le diagramme de définition DSL, sélectionnez le rôle à laquelle vous souhaitez que la propagation à supprimer.On the DSL Definition diagram, select the role to which you want propagation to delete. Le rôle est représenté par la ligne qui se trouve à gauche ou à droite d'une zone de relation de domaine.The role is represented by the line on the left or right of a domain relationship box.

    Par exemple, si vous voulez spécifier qu'à chaque fois qu'un album est supprimé les artistes associés doivent également être supprimés, vous devez sélectionner le rôle connecté à la classe de domaine Artiste.For example, if you want to specify that whenever an Album is deleted, the related Artists are also deleted, then select the role connected to the domain class Artist.

  2. Dans la fenêtre Propriétés, définissez la propage supprimer propriété.In the Properties window, set the Propagates Delete property.

  3. Appuyez sur F5 et vérifiez que :Press F5 and verify that:

    • Quand une instance de cette relation est supprimée, l'élément au rôle sélectionné sera également supprimé.When an instance of this relationship is deleted, the element at the selected role will also be deleted.

    • Quand un élément au rôle opposé est supprimé, les instances de cette relation seront supprimées et les éléments associés à ce rôle seront supprimés.When an element at the opposite role is deleted, instances of this relationship will be deleted, and the related elements at this role will be deleted.

    Vous pouvez également voir les propage supprimer option dans le détails DSL fenêtre.You can also see the Propagates Delete option in the DSL Details window. Sélectionnez une classe de domaine et, dans la fenêtre Détails DSL, ouvrez le supprimer le comportement page en cliquant sur le bouton situé sur le côté de la fenêtre.Select a domain class and, in the DSL Details window, open the Delete Behavior page by clicking the button at the side of the window. Le propager option ne s’affiche pour le rôle opposé de chaque relation.The Propagate option is shown for the opposite role of each relationship. Le supprimer le Style colonne indique si la propager option est à sa valeur par défaut, mais il n’a pas d’effet distinct.The Delete Style column indicates whether the Propagate option is at its default setting, but it does not have any separate effect.

Propagation de la suppression à l'aide de code de programmeDelete Propagation by using program code

Les options dans le fichier de définition DSL vous permettent uniquement de choisir si la suppression se propage à un voisin immédiat.The options in the DSL Definition file only let you choose whether deletion propagates to an immediate neighbor. Pour implémenter un modèle plus complexe de propagation de la suppression, vous pouvez écrire du code de programme.To implement a more complex scheme of delete propagation, you can write program code.

Note

Pour ajouter du code de programme à votre définition DSL, créez un fichier de code séparé dans le Dsl de projet et d’écrire des définitions partielles pour augmenter les classes dans le dossier de Code généré.To add program code to your DSL definition, create a separate code file in the Dsl project and write partial definitions to augment the classes in the Generated Code folder. Pour plus d’informations, consultez écriture de Code pour personnaliser un langage spécifique à un domaine.For more information, see Writing Code to Customise a Domain-Specific Language.

Définition d’une fermeture de suppressionDefining a Delete Closure

L’opération de suppression utilise la classe YourModelDeleteClosure pour déterminer les éléments à supprimer, une sélection initiale.The deletion operation uses the class YourModelDeleteClosure to determine which elements to delete, given an initial selection. Elle appelle ShouldVisitRelationship() et ShouldVisitRolePlayer() de manière répétée, en parcourant le graphique des relations.It calls ShouldVisitRelationship() and ShouldVisitRolePlayer() repeatedly, walking the graph of relationships. Vous pouvez substituer ces méthodes.You can override these methods. L'identité d'un lien et l'élément à l'un des rôles du lien sont fournis à la méthode ShouldVisitRolePlayer.ShouldVisitRolePlayer is provided with the identity of a link and the element at one of the link's roles. Elle doit retourner l'une des valeurs suivantes :It should return one of the following values:

  • VisitorFilterResult.Yes: l’élément doit être supprimé et que l’analyseur doit continuer à essayer l’élément d’autres liens.VisitorFilterResult.Yes- The element should be deleted and the walker should proceed to try the element's other links.

  • VisitorFilterResult.DoNotCare -l’élément ne doit pas être supprimé, sauf si une autre requête répond qu’il doit être supprimé.VisitorFilterResult.DoNotCare - The element should not be deleted unless another query replies that it should be deleted.

  • VisitorFilterResult.Never -l’élément de ne doit pas être supprimé, même si une autre requête répond Oui, et l’analyseur ne doit pas essayer l’élément d’autres liens.VisitorFilterResult.Never - The element must not be deleted, even if another query answers Yes, and the walker should not try the element's other links.

// When a musician is deleted, delete their albums with a low rating.
// Override methods in <YourDsl>DeleteClosure in DomainModel.cs
partial class MusicLibDeleteClosure
{
  public override VisitorFilterResult ShouldVisitRolePlayer
    (ElementWalker walker, ModelElement sourceElement, ElementLink elementLink,
    DomainRoleInfo targetDomainRole, ModelElement targetRolePlayer)
  {
    ArtistAppearsInAlbum link = elementLink as ArtistAppearsInAlbum;
    if (link != null
       && targetDomainRole.RolePlayer.Id == Album.DomainClassId)
    {
      // Count other unvisited links to the Album of this link.
      if (ArtistAppearsInAlbum.GetLinksToArtists(link.Album)
              .Where(linkAlbumArtist =>
                     linkAlbumArtist != link &&
                     !walker.Visited(linkAlbumArtist))
              .Count() == 0)
      {
        // Should delete this role player:
        return VisitorFilterResult.Yes;
      }
      else
        // Don't delete unless another relationship deletes it:
        return VisitorFilterResult.DoNotCare;
    }
    else
    {
      // Test for and respond to other relationships and roles here.

      // Not the relationship or role we're interested in.
      return base.ShouldVisitRolePlayer(walker, sourceElement,
             elementLink, targetDomainRole, targetRolePlayer);
    }
  }
}

La technique de fermeture garantit que le jeu d'éléments et de lien à supprimer est déterminé avant que la suppression ne commence.The closure technique ensures that the set of elements and links to be deleted is determined before deletion begins. L'analyseur combine aussi les résultats de votre fermeture avec ceux d'autres parties du modèle.The walker also combines the results of your closure with those from other parts of the model.

Toutefois, cette technique part du principe que la suppression affecte uniquement ses voisins dans le graphique des relations : vous ne pouvez pas appliquer cette méthode pour supprimer un élément dans une autre partie du modèle.However, the technique assumes that deletion affects only its neighbors in the graph of relationships: you cannot use this method to delete an element in another part of the model. Vous ne pouvez pas l'appliquer si vous souhaitez ajouter des éléments ou apporter d'autres modifications en réponse à une suppression.You cannot use it if you want to add elements or make other changes in response to a deletion.

À l’aide de OnDeleting et OnDeletedUsing OnDeleting and OnDeleted

Vous pouvez substituer OnDeleting() ou OnDeleted() dans une classe de domaine ou dans une relation de domaine.You can override OnDeleting() or OnDeleted() either in a domain class, or in a domain relationship.

  1. La méthode OnDeleting est appelée quand un élément est sur le point d'être supprimé, mais avant que ses relations aient été déconnectées.OnDeleting is called when an element is about to be deleted, but before its relationships have been disconnected. Il est encore accessible à partir d'autres éléments et se trouve toujours dans store.ElementDirectory.It is still navigable to and from other elements, and is still in store.ElementDirectory.

    Si plusieurs éléments sont supprimés en même temps, OnDeleting est appelée pour tous ces éléments avant d'effectuer les suppressions.If several elements are deleted at the same time, OnDeleting is called for all of them before performing the deletions.

    IsDeleting a la valeur True.IsDeleting is true.

  2. La méthode OnDeleted est appelée quand l'élément a été supprimé.OnDeleted is called when the element has been deleted. Il reste dans le tas CLR pour qu'une opération d'annulation puisse être effectuée si nécessaire, mais il n'est plus lié aux autres éléments et est supprimé de store.ElementDirectory.It remains in the CLR heap so that an Undo can be performed if required, but it is unlinked from other elements and removed from store.ElementDirectory. Pour les relations, les rôles de référencent toujours l’ancien acteurs de rôle.IsDeletedFor relationships, the roles still reference the old role players.IsDeleted a la valeur true.is true.

  3. Les méthode OnDeleting et OnDeleted sont appelées quand l'utilisateur appelle l'opération Annuler après avoir créé un élément et quand une suppression précédente est répétée dans Rétablir.OnDeleting and OnDeleted are called when the user invokes Undo after a creating an element, and when an earlier deletion is repeated in Redo. Utilisez this.Store.InUndoRedoOrRollback pour éviter de mettre à jour les éléments du magasin dans ces cas-là.Use this.Store.InUndoRedoOrRollback to avoid updating store elements in these cases. Pour plus d’informations, consultez Comment : utiliser les Transactions pour mettre à jour le modèle.For more information, see How to: Use Transactions to Update the Model.

    Par exemple, le code suivant supprime un album quand son dernier morceau enfant est supprimé :For example, the following code deletes an Album when its last child Song is deleted:


// Delete the parent Album when the last Song is deleted.
// Override methods in the embedding relationship between Album and Song:
partial class AlbumHasSongs
{
  protected override void OnDeleted()
  {
    base.OnDeleted();
    // Don't perform in-store actions in undo:
    if (this.Store.InUndoRedoOrRollback) return;
    // Relationship source and target still work:
    // Don't bother if source is already on its way out:
    if (!this.Album.IsDeleting && !this.Album.IsDeleted)
    {
      if (this.Album.Songs.Count == 0)
      {
        this.Album.Delete();
} } } }

Il est souvent plus utile de déclencher à partir de la suppression de la relation que de l'élément de rôle, car cela fonctionne à la fois quand l'élément est supprimé et quand la relation proprement dite est supprimée.It is often more useful to trigger from the deletion of the relationship than the role element, because this works both when the element is deleted, and when the relationship itself is deleted. Toutefois, pour une relation de référence, vous souhaiterez peut-être propager la suppression quand un élément associé est supprimé, mais pas quand la relation proprement dite est supprimée.However, for a reference relationship, you might want to propagate deletion when a related element is deleted, but not when the relationship itself is deleted. Cet exemple supprime un album quand son dernier artiste collaborateur est supprimé, mais ne répond pas si les relations sont supprimées :This example deletes an Album when its last contributing Artist is deleted, but it does not respond if the relationships are deleted:

using System.Linq; ...
// Assumes a many-many reference relationship
// between Artist and Album.
partial class Artist
{
  protected override void OnDeleting()
  {
    base.OnDeleting();
    if (this.Store.InUndoRedoOrRollback) return;
    List<Album> toDelete = new List<Album>();
    foreach (Album album in this.Albums)
    {
      if (album.Artists.Where(artist => !artist.IsDeleting)
                        .Count() == 0)
      {
        toDelete.Add(album);
      }
    }
    foreach (Album album in toDelete)
    {
      album.Delete();
} } }

Quand vous exécutez Delete sur un élément, OnDeleting et OnDeleted sont appelées.When you perform Delete on an element, OnDeleting and OnDeleted will be called. Ces méthodes sont toujours effectuée inline - autrement dit, immédiatement avant et après la suppression réelle.These methods are always performed inline - that is, immediately before and after the actual deletion. Si votre code supprime plusieurs éléments, OnDeleting et OnDeleted sont appelées en alternance sur tous ces éléments les uns après les autres.If your code deletes two or more elements, OnDeleting and OnDeleted will be called in alternation on all of them in turn.

Événements et règles de suppressionDeletion Rules and Events

En guise d'alternative aux gestionnaires OnDelete, vous pouvez définir des règles de suppression des événements de suppression.As an alternative to OnDelete handlers, you can define deletion rules and deletion events.

  1. Suppression de et supprimer règles sont déclenchées uniquement dans une transaction et pas d’annulation ou de restauration par progression.Deleting and Delete rules are triggered only in a transaction, and not in an Undo or Redo. Vous pouvez les configurer pour être mises en file d'attente pour s'exécuter à la fin de la transaction dans laquelle la suppression est effectuée.You can set them to be queued to execute at the end of the transaction in which the deletion is performed. Les règles Deleting sont toujours exécutées avant toute règle Deleted qui se trouve dans la file d'attente.Deleting rules are always executed before any Deleted rules that are in the queue.

    Utilisez des règles pour propager les modifications qui affectent uniquement des éléments du magasin, y compris des relations, des éléments de diagramme et leurs propriétés.Use rules to propagate changes that affect only elements in the store, including relationships, diagram elements and their properties. En général, une règle Deleting sert à propager la suppression et une règle Delete sert à créer des relations et des éléments de remplacement.Typically, a Deleting rule is used to propagate deletion, and a Delete rule is used to create replacement elements and relationships.

    Pour plus d’informations, consultez propager les modifications dans le modèle de règles.For more information, see Rules Propagate Changes Within the Model.

  2. Supprimé magasin événements est appelé à la fin d’une transaction et est appelée après une annulation ou de restauration par progression.Deleted store event is invoked at the end of a transaction, and is called after an undo or redo. Il peut donc servir à propager des suppressions à des objets en dehors du magasin, tels que des fichiers, des entrées de base de données ou d'autres objets dans Visual StudioVisual Studio.It can therefore be used to propagate deletions to objects outside the store such as files, database entries or other objects in Visual StudioVisual Studio.

    Pour plus d’informations, consultez gestionnaires propager les modifications en dehors du modèle d’événement.For more information, see Event Handlers Propagate Changes Outside the Model.

    Avertissement

    Quand un élément a été supprimé, vous pouvez accéder à ses valeurs de propriété de domaine, mais vous ne pouvez pas naviguer parmi les liens de relations.When an element has been deleted, you can access its domain property values, but you cannot navigate relationship links. Toutefois, si vous avez défini un événement deleted sur une relation, vous pouvez aussi accéder aux deux éléments qui étaient ses acteurs de rôle.However, if you set a deleted event on a relationship, you can also access the two elements that were its role players. Ainsi, si vous voulez répondre à la suppression d'un élément de modèle mais que vous souhaitez accéder un élément auquel il était lié, définissez un événement delete sur la relation plutôt que sur la classe de domaine de l'élément de modèle.Therefore, if you want to respond to the deletion of a model element but want to access an element to which it was linked, set a delete event on the relationship instead of the model element's domain class.

Exemple de règles de suppressionExample Deletion Rules

[RuleOn(typeof(Album), FireTime = TimeToFire.TopLevelCommit)]
internal class AlbumDeletingRule : DeletingRule
{
  public override void ElementDeleting(ElementDeletingEventArgs e)
  {
    base.ElementDeleting(e);
    // ...perform tasks to propagate imminent deletion
  }
}
[RuleOn(typeof(Album), FireTime = TimeToFire.TopLevelCommit)]
internal class AlbumDeletedRule : DeleteRule
{
  public override void ElementDeleted(ElementDeletedEventArgs e)
  {
    base.ElementDeleted(e);
    // ...perform tasks such as creating new elements
  }
}

// The rule must be registered:
public partial class MusicLibDomainModel
{
  protected override Type[] GetCustomDomainModelTypes()
  {
    List<Type> types = new List<Type>(base.GetCustomDomainModelTypes());
    types.Add(typeof(AlbumDeletingRule));
    types.Add(typeof(AlbumDeletedRule));
    // If you add more rules, list them here.
    return types.ToArray();
  }
}

Exemple d'événement DeletedExample Deleted Event

partial class NestedShapesSampleDocData
{
  protected override void OnDocumentLoaded(EventArgs e)
  {
    base.OnDocumentLoaded(e);
    DomainRelationshipInfo commentRelationship =
          this.Store.DomainDataDirectory
          .FindDomainRelationship(typeof(CommentsReferenceComponents));

    this.Store.EventManagerDirectory.ElementDeleted.Add(commentRelationship,
      new EventHandler<ElementDeletedEventArgs>(CommentLinkDeleted));
  }

  private void CommentLinkDeleted (object sender, ElementDeletedEventArgs e)
  {
    CommentsReferenceComponents link = e.ModelElement as CommentsReferenceComponents;
    Comment comment = link.Comment;
    Component component = link.Subject;
    if (comment.IsDeleted)
    {
      // The link was deleted because the comment was deleted.
      System.Windows.Forms.MessageBox.Show("Removed comment on " + component.Name);
    }
    else
    {
      // It was just the link that was deleted - the comment itself remains.
      System.Windows.Forms.MessageBox.Show("Removed comment link to "
           + component.Name);
    }
  }
}

Annuler la fusionUnMerge

L’opération qui associe un élément enfant à son parent est appelée fusion.The operation that attaches a child element to its parent is called merge. Elle a lieu quand un nouvel élément ou groupe d'éléments est créé à partir de la boîte à outils, déplacé à partir d'une autre partie du modèle ou copié à partir du Presse-papiers.It occurs when a new element or group of elements is created from the toolbox, or moved from another part of the model, or copied from the clipboard. En plus de créer une relation d'incorporation entre le parent et son nouvel enfant, l'opération de fusion peut aussi configurer des relations supplémentaires, créer des éléments auxiliaires et définir des valeurs de propriétés dans les éléments.As well as creating an embedding relationship between the parent and its new child, the merge operation can also set up additional relationships, create auxiliary elements, and set property values in the elements. L'opération de fusion est encapsulée dans une directive EMD (Element Merge Directive).The merge operation is encapsulated in an Element Merge Directive (EMD).

Un EMD encapsule les informations complémentaires annuler la fusion ou MergeDisconnect opération.An EMD also encapsulates the complementary unmerge or MergeDisconnect operation. Si vous avez un cluster d'éléments qui a été construit à l'aide d'une fusion, nous vous recommandons d'utiliser l'opération unmerge associée pour supprimer un élément de ce cluster si vous souhaitez conserver les éléments restants dans un état cohérent.If you have a cluster of elements that has been constructed by using a merge, it is recommended to use the associated unmerge to remove an element from it, if you want to leave the remaining elements in a consistent state. L'opération unmerge applique en général les techniques décrites dans les sections précédentes.The unmerge operation will typically use the techniques described in the previous sections.

Pour plus d’informations, consultez personnalisation de création d’éléments et le déplacement des.For more information, see Customizing Element Creation and Movement.

Voir aussiSee Also