Domanda

Ho un database MySql, la cui struttura generale è simile a questo:

Manufacturer <== ProbeDefinition <== ImagingSettings
  ElementSettings  ====^ ^==== ProbeInstance

sto usando InnoDB per consentire chiavi esterne, e tutte le chiavi esterne che punta a un ProbeDefinition ho posto ON DELETE CASCADE.

Il problema che sto avendo è quando elimino un ProbeDefinition nel mio codice, esso viene immediatamente reinserito. L'eliminazione a cascata avviene propriamente altre tabelle vengono cancellati, ma sembra che il LINQ to SQL potrebbe essere l'invio di un inserto per nessun motivo. Controllo la proprietà di modifiche sul database mostra 1 Elimina e no inserti.

Sto utilizzando la seguente piccola porzione di codice per eseguire l'eliminazione:

database.ProbeDefinition.DeleteOnSubmit(probe);
database.SubmitChanges();

Registri in MySql mostrano i seguenti comandi essendo eseguiti quando questo viene eseguito:

BEGIN
use `wetscoprobes`; DELETE FROM wetscoprobes.probedefinition WHERE ID = 10
use `wetscoprobes`; INSERT INTO wetscoprobes.probedefinition (CenterFrequency, Elements, ID, IsPhased, ManufacturerID, Name, Pitch, Radius, ReverseElements) VALUES (9500000, 128, 10, 1, 6, 'Super Probe 2', 300, 0, 1) 
COMMIT /* xid=2424 */

Che cosa ha potuto causare questo INSERT inutile? Si noti che l'eliminazione di un Manufacturer esattamente allo stesso modo cancella correttamente, con il seguente registro:

BEGIN 
use `wetscoprobes`; DELETE FROM wetscoprobes.manufacturer WHERE ID = 9 
COMMIT /* xid=2668 */ 

Modifica:. Dopo ulteriori test, sembra che questo succede solo dopo che ho popolato un ListBox con una lista di ProbeDefinitions

Ho provato a fare funzionare il codice di eliminazione sopra, prima e dopo il seguente frammento era corsa:

var manufacturer = (Manufacturer)cbxManufacturer.SelectedItem;
var probes = manufacturer.ProbeDefinition;

foreach (var probe in probes)
{
    cbxProbeModel.Items.Add(probe);
}

L'oggetto viene eliminato correttamente prima di detto codice ha funzionato, ma in qualsiasi momento dopo questo punto, esegue un inserto dopo l'eliminazione. Ha non piace il fatto che l'oggetto viene fatto riferimento da qualche parte?

Ecco il codice che sto correndo per testare l'eliminazione di una definizione dalla finestra intermedia:

database.ProbeDefinition.DeleteOnSubmit(database.ProbeDefinition.Last())
database.SubmitChanges()
È stato utile?

Soluzione

Risulta ci sono problemi quando ci sono più riferimenti all'oggetto. Facendo un passo attraverso la sorgente DbLinq, ho imparato che dopo un DELETE è completato, si passi attraverso tutti gli altri oggetti "guardato", alla ricerca di riferimenti.

In questo caso, ho più riferimenti attraverso il database.ProbeDefinition tavolo, così come attraverso il riferimento costruttore, manufacturer.ProbeDefinition. Questo non è un problema fino a quando ho letta oggetti attraverso entrambi i metodi. Utilizzando Remove possibile eliminare il riferimento dal produttore, utilizzando DeleteOnSubmit cancellerà l'oggetto dal tavolo. Se faccio uno o l'altro, l'altro riferimento esiste ancora, e quindi l'oggetto viene contrassegnato per essere reinserito. Non sono sicuro se questo è un bug in DbLinq che non elimina altri riferimenti, o comportamento previsto.

Ad ogni modo, nel mio caso, la soluzione è a uno accedere alla tabella utilizzando solo un unico metodo, ed eliminare utilizzando tale metodo o da eliminare utilizzando entrambi i metodi. Per il gusto di farlo funzionare, ho usato il secondo metodo:

// Delete probe
this.manufacturer.ProbeDefinition.Remove(probe);
database.ProbeDefinition.DeleteOnSubmit(probe);
database.SubmitChanges();

Modifica Su ulteriore lavoro sul progetto e problemi simili, ho trovato la vera questione di fondo della mia implementazione. Ho una lunga durata DataContext, e di come funziona la cache (per fare SubmitChanges lavoro), non si può fare questo. Il reale soluzione è quella di avere una vita breve DataContext, e ricollegare al database in ogni metodo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top