Pergunta

Eu tenho um banco de dados MySQL, cuja estrutura geral se parece com a seguinte:

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

Estou usando o Innodb para permitir chaves estrangeiras e todas as chaves estrangeiras apontando para um ProbeDefinition ter definido ON DELETE CASCADE.

O problema que estou tendo é quando excluo um ProbeDefinition No meu código, ele é imediatamente reinserido. A exclusão em cascata acontece corretamente para que outras tabelas sejam limpas, mas parece que o LINQ para SQL pode estar enviando uma inserção sem motivo. Verificando a propriedade Alteração no banco de dados mostra 1 exclusão e sem inserções.

Estou usando o seguinte pequeno código para executar o Excluir:

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

Os logs no MySQL mostram os seguintes comandos sendo executados quando isso é executado:

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

O que poderia causar isso desnecessário INSERT? Observe que excluir um Manufacturer Da mesma maneira, exclui corretamente, com o seguinte log:

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

Editar: Após mais testes, parece que isso só acontece depois que eu povoie uma caixa de listagem com uma lista de ProbeDefinitions.

Tentei executar o código de exclusão acima antes e depois que o snippet seguinte foi executado:

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

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

O objeto é excluído corretamente antes que o código do referido seja executado, mas a qualquer momento após esse ponto, ele executa uma inserção após a exclusão. Não gosta do fato de o objeto ser referenciado em algum lugar?

Aqui está o código que estou executando para testar a exclusão de uma definição da janela intermediária:

database.ProbeDefinition.DeleteOnSubmit(database.ProbeDefinition.Last())
database.SubmitChanges()
Foi útil?

Solução

Acontece que existem problemas quando há várias referências ao seu objeto. Passando pela fonte do dblinq, aprendi que depois de um DELETE está concluído, ele passa por todos os outros objetos "assistidos", procurando referências.

Nesse caso, tenho várias referências através da tabela database.ProbeDefinition bem como através da referência do fabricante, manufacturer.ProbeDefinition. Isso não é um problema até que eu tenha acessado objetos através dos dois métodos. Usando Remove pode excluir a referência do fabricante, usando DeleteOnSubmit excluirá o objeto da tabela. Se eu fizer um ou outro, a outra referência ainda existe e, portanto, o objeto está marcado para ser reinserido. Não tenho certeza se este é um bug no DBLINQ que ele não exclui outras referências ou comportamento esperado.

De qualquer forma, no meu caso, a solução é acessar a tabela usando apenas um método único e excluir usando esse método ou excluir usando os dois métodos. Para fazê -lo funcionar, usei o segundo método:

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

EDITAR: Após mais trabalhos no projeto e questões semelhantes, encontrei a verdadeira questão subjacente da minha implementação. Eu tenho um datacontext de longa duração e, com o funcionamento do cache (para fazer os submitchanges funcionarem), você não pode fazer isso. o real A solução é ter um datacontext de curta duração e reconectar-se ao banco de dados em cada método.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top