Stati degli oggetti e rilevamento delle modifiche (LINQ to SQL)
Agli oggetti LINQ to SQL è sempre associato uno stato. Ad esempio, quando in LINQ to SQL viene creato un nuovo oggetto, lo stato dell'oggetto è Unchanged. Un nuovo oggetto creato dall'utente è sconosciuto all'oggetto DataContext e si trova nello stato Untracked. Dopo la corretta esecuzione di SubmitChanges, tutti gli oggetti riconosciuti da LINQ to SQL sono nello stato Unchanged. La sola eccezione è rappresentata dagli oggetti eliminati dal database che sono nello stato Deleted e di conseguenza inutilizzabili in quell'istanza di DataContext.
Stati degli oggetti
Nella tabella seguente sono elencati gli stati possibili per gli oggetti LINQ to SQL.
Stato |
Descrizione |
---|---|
Untracked |
Un oggetto non registrato da LINQ to SQL. Di seguito vengono forniti alcuni esempi:
|
Unchanged |
Un oggetto recuperato utilizzando l'istanza corrente di DataContext e che non risulta modificato da quando è stato creato. |
PossiblyModified |
Un oggetto associato a un'istanza di DataContext. Per ulteriori informazioni, vedere Recupero dei dati e operazioni CUD in applicazioni a più livelli (LINQ to SQL). |
ToBeInserted |
Un oggetto non recuperato utilizzando l'istanza corrente di DataContext. In questo caso viene eseguita un'operazione INSERT in un database durante l'esecuzione di SubmitChanges. |
ToBeUpdated |
Un oggetto che risulta modificato da quando è stato recuperato. In questo caso viene eseguita un'operazione UPDATE in un database durante l'esecuzione di SubmitChanges. |
ToBeDeleted |
Un oggetto contrassegnato per l'eliminazione, che causa un'operazione DELETE in un database durante l'esecuzione di SubmitChanges. |
Deleted |
Un oggetto eliminato nel database. Questo stato è finale e non consente transizioni aggiuntive. |
Inserimento di oggetti
È possibile richiedere Inserts utilizzando InsertOnSubmit in modo esplicito. In alternativa, in LINQ to SQL è possibile dedurre l'oggetto Inserts mediante la ricerca di oggetti collegati a uno degli oggetti conosciuti che devono essere aggiornati. Ad esempio, se si aggiunge un oggetto Untracked a un oggetto EntitySet<TEntity> o si imposta un oggetto EntityRef<TEntity> su un oggetto Untracked, si rende raggiungibile l'oggetto Untracked mediante gli oggetti rilevati nel grafico. Durante l'elaborazione dell'oggetto SubmitChanges, in LINQ to SQL vengono attraversati gli oggetti rilevati e individuato qualsiasi oggetto persistente raggiungibile di cui non è stata tenuta traccia. Tali oggetti sono candidati per l'inserimento nel database.
Per le classi in una gerarchia di ereditarietà, InsertOnSubmit(o) imposta inoltre il valore del membro definito come discriminatore in modo che corrisponda al tipo dell'oggetto o. Qualora un tipo dovesse corrispondere al valore discriminante predefinito, questa azione causerà la sovrascrittura del valore discriminante con il valore predefinito. Per ulteriori informazioni, vedere Supporto dell'ereditarietà (LINQ to SQL).
Importante |
---|
Un oggetto aggiunto a un oggetto Table non si trova nella cache delle identità,che riflette solo gli oggetti recuperati dal database.Dopo una chiamata a InsertOnSubmit, l'entità aggiunta non viene visualizzata nelle query eseguite sul database finché non si completerà SubmitChanges. |
Eliminazione di oggetti
Per contrassegnare per l'eliminazione un oggetto o rilevato, chiamare DeleteOnSubmit(o) sull'oggetto Table<TEntity> appropriato. In LINQ to SQL la rimozione di un oggetto da un oggetto EntitySet<TEntity> viene considerata come un'operazione di aggiornamento e il valore della chiave esterna corrispondente viene impostato su Null. La destinazione dell'operazione (o) non viene eliminata dalla relativa tabella. Ad esempio, cust.Orders.DeleteOnSubmit(ord) indica un aggiornamento in cui la relazione tra cust e ord viene interrotta mediante l'impostazione della chiave esterna ord.CustomerID su null. Non causa l'eliminazione della riga che corrisponde a ord.
Quando un oggetto viene eliminato (DeleteOnSubmit) dalla relativa tabella, in LINQ to SQL viene eseguita l'elaborazione seguente:
Quando si chiama SubmitChanges, per quell'oggetto viene eseguita un'operazione DELETE.
La rimozione non viene propagata agli oggetti correlati, indipendentemente dallo stato di caricamento. In particolare, gli oggetti correlati non vengono caricati per aggiornare la proprietà della relazione.
Dopo la corretta esecuzione di SubmitChanges, gli oggetti vengono impostati sullo stato Deleted. Di conseguenza non sarà possibile utilizzare l'oggetto o il relativo id in un'istanza di DataContext. La cache interna gestita da un'istanza di DataContext non elimina gli oggetti recuperati o aggiunti come nuovi, anche dopo che sono stati eliminati nel database.
È possibile chiamare DeleteOnSubmit solo su un oggetto registrato da DataContext. Per un oggetto Untracked è necessario chiamare Attach prima di DeleteOnSubmit. Chiamando DeleteOnSubmit su un oggettoUntracked, verrà generata un'eccezione.
Nota |
---|
La rimozione di un oggetto da una tabella indica a LINQ to SQL di generare un comando SQL DELETE corrispondente al momento dell'esecuzione dell'oggetto SubmitChanges.Questa azione non rimuove l'oggetto dalla cache, né propaga l'eliminazione agli oggetti correlati. Per recuperare l'id di un oggetto eliminato, utilizzare una nuova istanza di DataContext.Per la pulizia degli oggetti correlati è possibile utilizzare la funzionalità del database per la propagazione in cascata di un'eliminazione oppure eliminare manualmente gli oggetti correlati. Non è necessario, a differenza del database, eliminare gli oggetti correlati in un ordine particolare. |
Aggiornamento di oggetti
È possibile rilevare l'esecuzione di Updates osservando le notifiche delle modifiche, che vengono fornite tramite l'evento PropertyChanging nei metodi per l'impostazione delle proprietà. Quando LINQ to SQL riceve una notifica della prima modifica a un oggetto, crea una copia dell'oggetto e lo considera candidato per la generazione di un'istruzione Update.
Per gli oggetti che non implementano l'oggetto INotifyPropertyChanging, in LINQ to SQL viene mantenuta una copia dei valori degli oggetti quando sono stati materializzati per la prima volta. Quando si chiama l'oggetto SubmitChanges, in LINQ to SQL vengono confrontati i valori originali e correnti per stabilire se l'oggetto è stato modificato.
Per gli aggiornamenti delle relazioni, il riferimento dal figlio al padre, ovvero il riferimento che corrisponde alla chiave esterna, viene considerato autorevole. Il riferimento nella direzione inversa, ovvero da padre a figlio, è facoltativo. Le classi di relazione (EntitySet<TEntity> e EntityRef<TEntity>) assicurano che i riferimenti bidirezionali siano coerenti per le relazioni uno-a-molti e uno-a-uno. Se il modello a oggetti non utilizza EntitySet<TEntity> o EntityRef<TEntity> e se è presente il riferimento inverso, sarà necessario mantenerlo coerente con il riferimento in avanti quando viene aggiornata la relazione.
Se si aggiornano sia il riferimento obbligatorio che la chiave esterna corrispondente, è necessario assicurarsi che corrispondano. Se non sono entrambi sincronizzati quando si chiama SubmitChanges, verrà generata un'eccezione InvalidOperationException. Anche se le modifiche dei valori della chiave esterna sono sufficienti per interessare un aggiornamento della riga sottostante, è necessario modificare il riferimento per mantenere la connettività dell'oggetto grafico e la coerenza bidirezionale delle relazioni.
Vedere anche
Concetti
Operazioni Insert, Update e Delete (LINQ to SQL)