Personalizar el comportamiento de eliminación
Eliminar un elemento aparece normalmente los elementos relacionados que se eliminarán también.todas las relaciones conectaron con él, y se elimina cualquier elemento secundario.Este comportamiento se denomina propagación de cancelación.Puede personalizar la propagación de cancelación, por ejemplo para organizar que los elementos relacionados adicionales se eliminarán.Escribir código de programa, puede hacer que la cancelación la propagación depende del estado del modelo.También puede realizar otros cambios aparezcan en respuesta a una eliminación.
En este tema, se incluyen las siguientes secciones:
Comportamiento predeterminado de eliminación
estableciendo la propagación elimine la opción de un rol
Reemplazar delete Closure – utilice esta técnica donde la eliminación podría provocar la eliminación de elementos vecinos.
Mediante OnDeleting y OnDeleted – utilice estos métodos dentro del cual la respuesta podría incluir otras acciones como actualizar un valor o fuera del almacén.
Reglas de eliminación – reglas de uso para propagar las actualizaciones de la clase de almacén, donde un cambio puede conducir a otros.
Eventos de eliminación – eventos de almacén de uso para propagar fuera de las actualizaciones el almacén, por ejemplo a otros documentos de Visual Studio .
UnMerge – utilice la operación de UnMerge para deshacer la operación de combinación que asocia un elemento secundario a su elemento primario.
Comportamiento predeterminado de eliminación
De forma predeterminada, las reglas siguientes rigen la propagación de cancelación:
si se elimina un elemento, todos los elementos incrustados también se eliminan.Los elementos incrustados son los que son destinos de relaciones de incrustación para las que este elemento es el origen.Por ejemplo, si hay una relación de incrustación de álbum a Song, después cuando se elimina un álbum determinado, todo el Songs también es eliminado.
Por el contrario, eliminar una canción no elimina el álbum.
De forma predeterminada, la eliminación no se propaga a lo largo de relaciones de referencia.Si existe una relación ArtistPlaysOnAlbum de la referencia del álbum a Artist, eliminar un álbum no elimina ningún artista relacionado, y eliminar un artista no elimina ningún álbum.
Sin embargo, la eliminación se propaga a lo largo de algunas relaciones integradas.Por ejemplo, cuando se elimina un elemento del modelo, su forma en el diagrama también se elimina.El elemento y la forma que están relacionados por la relación de referencia de PresentationViewsSubject .
Se elimina todas las relaciones que se conecta con el elemento, en el rol de origen o de destino.La propiedad del elemento en el rol contrario no contenga el elemento eliminado.
estableciendo la propagación elimine la opción de un rol
Puede producir la eliminación a la propagación a lo largo de una relación de referencia, o un elemento secundario incrustado a su elemento primario.
Para establecer la propagación de cancelación
En el diagrama de la definición de DSL, seleccione el rol al que desea propagación para eliminar.El rol es representado por la línea a la izquierda o derecha de un cuadro de la relación de dominio.
Por ejemplo, si desea especificar siempre que se elimine un álbum, el Artists relacionado también se elimina, seleccione el rol conectado a la clase Artist de dominio.
en la ventana Propiedades, establezca la propiedad de Propaga Suprimir .
Presione F5 y compruebe que:
Cuando una instancia de esta relación se elimina, el elemento en el rol seleccionado también se eliminará.
Cuando un elemento del rol contrario se elimina, las instancias de esta relación se eliminarán, y los elementos relacionados en este rol se eliminarán.
También puede ver la opción de Propaga Suprimir en la ventana de Detalles ADSL .Seleccione una clase de dominio y, en la ventana de detalles ADSL, abra la página de elimine el comportamiento haciendo clic en el botón en el lado de la ventana.la opción de propagación se muestra para el rol opuesto de cada relación.La columna de Estilo delete indica si la opción de propagación está en su configuración predeterminada, pero no tiene ningún efecto independiente.
Suprimir Propagation utilizando código de programa
Las opciones del archivo de definición ADSL permiten sólo elegir si la eliminación se propaga a un vecino inmediato.Para implementar un esquema más complejo de propagación de cancelación, puede escribir código de programa.
[!NOTA]
Para agregar código de programa a la definición ADSL, cree un archivo de código independiente en el proyecto de Dsl y escriba las definiciones parciales para aumentar las clases en la carpeta de código generado.Para obtener más información, vea Escribir código para personalizar lenguajes específicos de dominio.
Definir una Suprimir Closure
La operación de eliminación utiliza la clase TheModelDeleteClosure para determinar qué elementos a eliminar, dada una selección inicial.Llama a ShouldVisitRelationship() y ShouldVisitRolePlayer() repetidamente, recorrer el gráfico de relaciones.Puede invalidar estos métodos.ShouldVisitRolePlayer se proporciona la identidad de un vínculo y elementos en uno de los roles de vínculo.Debe devolver uno de los siguientes valores:
VisitorFilterResult.Yes– el elemento se debe eliminar y el rastreador debe continuar para intentar otros vínculos del elemento.
VisitorFilterResult.DoNotCare – el elemento de no debe eliminarse a menos que otra consulta que debe eliminarse.
VisitorFilterResult.Never – el elemento de no debe eliminar, incluso si otra consulta responde Yes, y el rastreador no debe intentar otros vínculos del elemento.
// 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 técnica de cierre garantiza que determinan el conjunto de elementos y vínculos se eliminen antes de que comience la eliminación.El rastreador también combina los resultados de cierre con los de otras partes del modelo.
Sin embargo, la técnica supone que la eliminación solo afecta a los vecinos en el gráfico de relaciones: no puede utilizar este método para eliminar un elemento en otra parte del modelo.No se puede usar si desea agregar elementos o realizar otros cambios en respuesta a una eliminación.
Mediante OnDeleting y OnDeleted
Puede reemplazar OnDeleting() o OnDeleted() en una clase de dominio, o en una relación del dominio.
se llamaOnDeleting cuando un elemento se va a eliminar, pero antes de que se han desconectado sus relaciones.Todavía es navegable a y desde otros elementos, y continúa en store.ElementDirectory.
Si varios elementos se eliminan al mismo tiempo, OnDeleting se llama para todos antes de realizar las eliminaciones.
IsDeleting es true.
se llamaOnDeleted cuando se ha eliminado el elemento.Permanece en el montón CLR para poder realizar una operación de deshacer si es necesario, pero se desata de otros elementos y se quita de store.ElementDirectory.Para las relaciones, los roles todavía hace referencia a los antiguos encargados de función.IsDeleted es true.
Se llama OnDeleting y OnDeleted cuando el usuario invoca undo después de crear un elemento, y cuando una eliminación anterior se repite en rehacer.Uso this.Store.InUndoRedoOrRollback de impedir actualizar elementos almacenados en estos casos.Para obtener más información, vea Cómo: Usar transacciones para actualizar el modelo.
Por ejemplo, el código siguiente elimina un álbum cuando eliminan a se Song:
// 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();
} } } }
Suele ser más útil desencadenar de eliminación de la relación que el rol del elemento, porque funciona esto tanto cuando se elimina el elemento y, cuando se elimina la relación propio.Sin embargo, para una relación de referencia, para propagar la eliminación cuando se elimina un elemento relacionado, pero no cuando se elimina la relación propio.Este ejemplo elimina un álbum cuando se elimina el Artist participante pasado, pero no responde si se eliminan las relaciones:
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();
} } }
Cuando se realiza Delete en un elemento, OnDeleting y OnDeleted se llamará.Estos métodos son siempre especificado realizado (es decir, inmediatamente antes y después de la eliminación real.Si el código elimina dos o más elementos, OnDeleting y OnDeleted se llamará en la alternancia de todos a la vez.
Reglas y eventos de eliminación
Como alternativa a los controladores de OnDelete, puede definir las reglas de eliminación y eventos de eliminación.
Deleting y las reglas de Delete se desencadenan sólo en una transacción, y no en una operación de deshacer o rehacer.Puede establecer que se podrán en cola para ejecutarse al final de la transacción en la que se realiza la eliminación.Eliminar reglas siempre se ejecutan antes de cualquier regla eliminada que esté en la cola.
Reglas de uso para propagar los cambios que afectan a elementos en el almacén, incluidas las relaciones, elementos del diagrama y sus propiedades.Normalmente, se utiliza una regla que elimina para propagar la eliminación, y se utiliza una regla delete para crear elementos y relaciones de reemplazo.
Para obtener más información, vea Las reglas propagan los cambios dentro del modelo.
el evento del almacén deDeleted se invoca al final de una transacción, y se denomina después de una operación de deshacer o de una operación de rehacer.Por lo que puede utilizar para propagar eliminaciones a objetos fuera del almacén como archivos, entradas de la base de datos u otros objetos en Visual Studio.
Para obtener más información, vea Los controladores de eventos propagan cambios fuera del modelo.
Precaución Cuando se ha eliminado un elemento, se puede obtener acceso a los valores de propiedad de dominio, pero no puede navegar los vínculos de la relación.Sin embargo, si establece un evento eliminado en una relación, también puede tener acceso a los dos elementos que eran los encargados de función.Por consiguiente, si desea responder a la eliminación de un elemento de modelo pero que desee tener acceso a un elemento al que se vinculó, establezca un evento de cancelación en la relación en lugar de la clase del modelo de dominio del elemento.
Reglas de la eliminación de ejemplo
[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();
}
}
evento eliminado ejemplo
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);
}
}
}
UnMerge
La operación que asocia un elemento secundario a su elemento primario se denomina combinación.Se produce cuando crean de cuadro de herramientas, o se mueven desde otra parte del modelo, o se copian un nuevo elemento o grupo de elementos del portapapeles.Así como crear una relación de incrustación entre el elemento primario y el nuevo elemento secundario, la operación de combinación puede configurar relaciones adicionales, crea elementos auxiliares, y valores de propiedad en los elementos.La operación de combinación se encapsula en una directiva de la combinación de elementos (EMD).
Un EMD también encapsula el unmerge u operación complementario de MergeDisconnect .Si tiene un clúster de elementos que se ha construido utilizando una combinación, se recomienda utilizar el unmerge asociado para quitar un elemento de, si desea dejar los elementos restantes en un estado coherente.La operación de unmerge utilizará normalmente las técnicas descritas en las secciones anteriores.
Para obtener más información, vea Personalizar la creación y el movimiento de los elementos.
Vea también
Conceptos
Personalizar comportamiento de copia
Personalizar la creación y el movimiento de los elementos
Otros recursos
Escribir código para personalizar lenguajes específicos de dominio