Personalizzazione del comportamento di eliminazione
Rimuovere un elemento in genere determina gli elementi correlati a essere eliminato anche.Tutte le relazioni sono connesse a e tutti gli elementi figlio vengono eliminati.questo comportamento è denominato propagazione di eliminazione.È possibile personalizzare la propagazione di eliminazione, ad esempio per fare in modo che gli elementi correlati aggiuntivi vengono eliminati.Scrive codice di programma, è possibile effettuare l'eliminazione la propagazione dipendere dallo stato del modello.È inoltre possibile eseguire altre modifiche a verificare in risposta a un'eliminazione.
In questo argomento sono incluse le seguenti sezioni:
comportamento predefinito di eliminazione
Impostando la propagazione rimuovere l'opzione di un ruolo
Eseguire l'override della chiusura di eliminazione - Utilizzare questa tecnica dove l'eliminazione potrebbe causare eliminazione di elementi adiacenti.
Utilizzando OnDeleting e di OnDeleted - Utilizzare questi metodi in cui la risposta potrebbe includere altre azioni come aggiornare un valore all'interno o all'archivio.
regole di eliminazione - Regole di utilizzo propagare gli aggiornamenti di qualsiasi tipo all'interno dell'archivio, in cui una modifica può influire negativamente su altre.
eventi di eliminazione - Eventi dell'archivio di utilizzo per propagare gli aggiornamenti all'esterno dell'archivio, ad esempio a un altro Visual Studio documenti.
UnMerge - utilizzare l'operazione di UnMerge per annullare l'operazione di unione che ha associato un elemento figlio al padre.
comportamento predefinito di eliminazione
Per impostazione predefinita, le regole seguenti per la propagazione di eliminazione:
Se un elemento viene eliminato, tutti gli elementi incorporati vengono eliminati anche.Gli elementi incorporati sono quelli che sono le destinazioni di incorporare le relazioni per il quale questo elemento è il database di origine.Ad esempio, se c " è una relazione che utilizza dall'album a un brano, pertanto quando un album particolare viene eliminato, tutte le canzoni verranno eliminati anche.
Al contrario, eliminando una canzone non elimina l'album.
Per impostazione predefinita, la non si propaga lungo le relazioni di riferimento.Se c " è una relazione di riferimento ArtistPlaysOnAlbum dall'album all'artista, eliminando un album non eliminare alcun artista correlato ed eliminazione di un artista non eliminare alcun album.
Tuttavia, la si propaga lungo alcune relazioni incorporate.Ad esempio, quando si elimina un elemento di modello, la sua forma del diagramma viene eliminata anche.L'elemento e la forma sono correlati da PresentationViewsSubject relazione di riferimento.
Ogni relazione che è connessa all'elemento, al database di origine o al ruolo di destinazione, viene eliminato.Il ruolo della proprietà del ruolo opposto più non contiene l'elemento eliminato.
Impostando la propagazione rimuovere l'opzione di un ruolo
È possibile impedire l'eliminazione a propagata lungo una relazione di riferimento, o da un figlio incorporato per il relativo padre.
Per impostare propagazione di eliminazione
Nel diagramma della definizione di modello DSL, selezionare ruolo a cui si desidera che la propagazione da eliminare.Il ruolo è rappresentato dalla linea a sinistra o a destra della casella di relazione di dominio.
Ad esempio, se si desidera specificare che ogni volta che un album viene eliminato, gli artisti correlati vengono eliminati anche, quindi per selezionare il ruolo connesso all'artista classi di dominio.
Nella Finestra Proprietà, impostare Eliminazione di propagazioni proprietà.
Premere F5 e verificare gli aspetti seguenti:
Quando un'istanza di questa relazione viene eliminata, l'elemento al ruolo selezionato verranno eliminati anche.
Quando un elemento al ruolo opposto viene eliminato, le istanze di questa relazione verranno eliminate e gli elementi correlati in questo ruolo verranno eliminate.
È inoltre possibile vedere Eliminazione di propagazioni opzione in Dettagli DSL finestra.Selezionare una classe di dominio e, nella finestra dettagli DSL, aprire Comportamento dell'eliminazione pagina facendo clic sul pulsante a destra della finestra.propagazione l'opzione è indicata per il ruolo opposto di ogni relazione.Stile di eliminazione la colonna indica se propagazione l'opzione è a sua impostazione predefinita, ma non dispone di alcuna effetto separato.
Propagazione di eliminazione tramite codice programma
Le opzioni nel file di definizione DSL consentono di scegliere solo se l'eliminazione viene estesa a un oggetto immediato.Per implementare una combinazione più complessa di propagazione di eliminazione, è possibile scrivere codice programma.
[!NOTA]
Per aggiungere il codice del programma alla definizione di modello DSL, creare un file di codice distinto in Dsl project e scrivere le definizioni parziali per aumentare le classi nella cartella codice generato.Per ulteriori informazioni, vedere Scrittura di codice per personalizzare un linguaggio specifico di dominio.
Definizione della chiusura di eliminazione
l'operazione di eliminazione utilizza la classe TheModelDeleteClosure per determinare quali elementi per eliminare, in base a una selezione iniziale.chiama ShouldVisitRelationship() e ShouldVisitRolePlayer() ripetutamente, scorrendo il grafico delle relazioni.È possibile eseguire l'override di questi metodi.ShouldVisitRolePlayer viene fornito identità di un collegamento e dell'elemento con uno dei ruoli di collegamento.Deve restituire uno dei seguenti valori:
VisitorFilterResult.Yes- L'elemento deve essere eliminato e il percorso chiamate in deve continuare a utilizzare altri collegamenti dell'elemento.
VisitorFilterResult.DoNotCare - L'elemento non deve essere eliminato a meno che un altro query ha risposto da eliminare.
VisitorFilterResult.Never - L'elemento non deve essere eliminato, anche se un altro risposte di query Yese il percorso chiamate in non deve tentare altri collegamenti dell'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 tecnica di chiusura garantisce che il set di elementi e collegamenti vengono eliminati sia determinato prima che inizi l'eliminazione.Il percorso chiamate in inoltre combina i risultati di chiusura con quelli di altre parti del modello.
Tuttavia, la tecnica si presuppone che l'eliminazione interesse solo gli elementi adiacenti nel grafico delle relazioni: non è possibile utilizzare questo metodo per rimuovere un elemento in un'altra parte del modello.Non è possibile utilizzarla se si desidera aggiungere gli elementi o apportare altre modifiche in risposta a un'eliminazione.
Utilizzando OnDeleting e di OnDeleted
È possibile eseguire l'override OnDeleting() o OnDeleted() in una classe di dominio, o in una relazione di dominio.
OnDeleting viene chiamato quando un elemento sta per essere eliminato, ma prima che le relative relazioni siano state disconnesse.È ancora esplorabile in e da altri elementi ed è ancora in store.ElementDirectory.
Se alcuni elementi eliminati contemporaneamente, OnDeleting viene chiamato per tutti prima di eseguire le eliminazioni.
IsDeleting è true.
OnDeleted viene chiamato quando l'elemento è stato eliminato.Rimane nell'heap CLR in modo da poter eseguire un'operazione di annullamento se necessario, ma è sconnessa da altri elementi e viene rimossa da store.ElementDirectory.Per le relazioni, i ruoli ancora fanno riferimento a giocatori di ruolo aggiornata.IsDeleted è true.
OnDeleting e OnDeleted chiamati durante la fase dell'utente richiama il comando annulla dopo creare un elemento e quando un'eliminazione precedente viene ripetuta nella ripetizione.utilizzo this.Store.InUndoRedoOrRollback per evitare aggiornare gli elementi memorizzati in questi casi.Per ulteriori informazioni, vedere Procedura: utilizzare le transazioni per aggiornare il modello.
Ad esempio, il codice riportato di seguito consente di eliminare un album quando la l'ultima brano figlio viene eliminato:
// 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();
} } } }
È spesso molto utile attivare dall'eliminazione della relazione che il ruolo dell'elemento, poiché questo funziona sia quando l'elemento viene eliminato e quando la relazione stessa viene eliminato.Tuttavia, per una relazione di riferimento, potrebbe essere necessario propagare l'eliminazione quando un elemento correlato viene eliminato, ma non quando la relazione stessa viene eliminato.In questo esempio viene eliminato un album quando il relativo l'ultimo artista di supporto viene eliminato, ma non risponde se le relazioni vengono eliminati:
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();
} } }
Quando si eseguono Delete in un elemento, OnDeleting e OnDeleted verranno chiamati.Questi metodi sono sempre inline eseguito, ovvero immediatamente prima di e dopo effettiva eliminazione.Se il codice consente due o più elementi, OnDeleting e OnDeleted verranno chiamati nell'alternanza su tutti a sua volta.
Regole e gli eventi di eliminazione
Come alternativa ai gestori di OnDelete, è possibile definire regole di eliminazione e gli eventi di eliminazione.
Deleting e Delete le regole vengono attivati solo in una transazione e non in un'operazione di annullamento o di ripetizione.È possibile impostarli accodare per eseguire al termine della transazione nella quale l'eliminazione viene eseguita.Eliminazione delle regole vengono sempre eseguiti prima che tutte le regole si elimina presenti nella coda.
Regole di utilizzo propagare le modifiche che influiscono unicamente sugli elementi nell'archivio, incluse le relazioni, gli elementi del diagramma e le relative proprietà.In genere, una regola di viene utilizzata per propagare l'eliminazione e una regola di eliminazione viene utilizzata per creare elementi e relazioni di sostituzione.
Per ulteriori informazioni, vedere Le regole propagano le modifiche all'interno del modello.
Deleted l'evento dell'archivio viene richiamato alla fine di una transazione e viene chiamato dopo un'operazione di annullamento o ripetizione.Pertanto può essere utilizzato per propagare le eliminazioni agli oggetti fuori dell'archivio come file, voci di database o altri oggetti in Visual Studio.
Per ulteriori informazioni, vedere I gestori eventi propagano le modifiche al di fuori del modello.
Attenzione Quando un elemento è stato eliminato, è possibile accedere ai relativi valori di proprietà del dominio, ma non è possibile passare i collegamenti della relazione.Tuttavia, se si imposta un evento eliminato in una relazione, è anche possibile accedere ai due elementi che costituiscono i relativi giocatori di ruolo.Pertanto, se si desidera rispondere all'eliminazione di un elemento del modello ma si desidera accedere a un elemento su cui è stato collegato, impostare un evento elimina sulla relazione alla classe di dominio dell'elemento del modello.
regole di esempio di eliminazione
[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 eliminato esempio
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
L'operazione che associa un elemento figlio al padre viene chiamata unione.Si verifica quando un nuovo elemento o gruppo di elementi viene creato dalla casella degli strumenti, o viene spostato in un'altra parte del modello, o viene copiato dagli Appunti.Così come creare una relazione che utilizza tra il padre e il nuovo elemento figlio, l'operazione di unione inoltre possibile impostare le relazioni aggiuntive, crea elementi ausiliari e i valori di proprietà impostati gli elementi.L'operazione di unione viene incapsulato in una direttiva di unione (EMD) dell'elemento.
Un EMD anche incapsula il completamento unmerge o MergeDisconnect operazione.Se si dispone di un cluster degli elementi che è stato creato un'unione, si consiglia di utilizzare il unmerge associato per eliminare un elemento da, se si desidera conservare gli elementi rimanenti in uno stato coerente.L'operazione di unmerge utilizzerà in genere le tecniche descritte nelle sezioni precedenti.
Per ulteriori informazioni, vedere Personalizzazione della creazione e dello spostamento di elementi.
Vedere anche
Concetti
Personalizzazione del comportamento di copia
Personalizzazione della creazione e dello spostamento di elementi
Altre risorse
Scrittura di codice per personalizzare un linguaggio specifico di dominio