L'objet est réinséré dans la base de données immédiatement après suppression (DbLinq)

StackOverflow https://stackoverflow.com/questions/2157746

  •  23-09-2019
  •  | 
  •  

Question

J'ai une base de données MySql, dont la structure générale ressemble à ceci:

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

J'utilise InnoDB pour permettre des clés étrangères, et toutes les clés étrangères pointant vers un ProbeDefinition ont mis ON DELETE CASCADE.

La question que je vais avoir est quand je supprime un ProbeDefinition dans mon code, il se immédiatement réinséré. La suppression en cascade se produit correctement si d'autres tables sont effacées, mais il semble que le LINQ to SQL peut envoyer un insert sans raison. Vérification de la propriété ChangeSet sur la base de données montre 1 delete, et aucune insertion.

J'utilise le petit peu de code suivant pour effectuer la suppression:

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

Journaux de MySql montrent les commandes suivantes en cours d'exécution lorsque cela est exécuté:

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 */

Ce qui pourrait causer cette INSERT inutile? Notez que la suppression d'un Manufacturer de la même manière exacte correctement supprime, avec le journal suivant:

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

Edit:. Sur d'autres tests, il semble que cela se produit seulement après que je l'ai peuplé ListBox avec une liste de ProbeDefinitions

J'ai essayé de courir le code suppression ci-dessus avant et après l'extrait suivant avait couru:

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

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

L'objet est supprimé correctement avant que ledit code est exécuté, mais à tout moment après ce point, il effectue une insertion après la suppression. Est-ce pas le fait que l'objet est référencé quelque part?

Voici le code que je suis en cours d'exécution pour tester la suppression d'une définition de la fenêtre intermédiaire:

database.ProbeDefinition.DeleteOnSubmit(database.ProbeDefinition.Last())
database.SubmitChanges()
Était-ce utile?

La solution

Turns out il y a des problèmes quand il y a plusieurs références à votre objet. Parcourant la source DbLinq, j'ai appris qu'après un DELETE est terminé, il étapes à travers tous les autres objets « surveillés », à la recherche de références.

Dans ce cas, j'ai plusieurs références à travers la table database.ProbeDefinition ainsi que par la référence fabricant, manufacturer.ProbeDefinition. Ce n'est pas un problème jusqu'à ce que j'ai accès des objets à travers les deux méthodes. L'utilisation Remove peut supprimer la référence du fabricant, en utilisant DeleteOnSubmit supprime l'objet de la table. Si je fais un ou l'autre, l'autre référence existe toujours, et donc l'objet est marqué pour être réinséré. Je ne sais pas si cela est un bogue dans DbLinq qu'il ne supprime pas d'autres références, ou le comportement attendu.

De toute façon, dans mon cas, la solution consiste à accéder à la table en utilisant une seule méthode, et supprimer en utilisant cette méthode, ou à supprimer à l'aide des deux méthodes. Pour des raisons de le faire marcher, je la deuxième méthode:

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

EDIT: À la poursuite des travaux sur le projet et des problèmes similaires, j'ai trouvé la vraie question sous-jacente de ma mise en œuvre. J'ai un DataContext long vécu, et avec la façon dont fonctionne la mise en cache (pour faire fonctionner SubmitChanges), vous ne pouvez pas le faire. real solution est d'avoir un DataContext de courte durée, et se reconnecter à la base de données dans chaque méthode.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top