2010-01-28 1 views
0

У меня есть база данных MySql, чья общая структура выглядит следующим образом:Объект повторно в базу данных сразу после удаления (DbLinq)

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

Я использую InnoDB, чтобы внешние ключи, и все внешние ключи, указывающие на a ProbeDefinition есть ON DELETE CASCADE.

Проблема, с которой я сталкиваюсь, - это когда я удаляю ProbeDefinition в своем коде, он сразу же вводится повторно. Каскадное удаление происходит правильно, поэтому другие таблицы очищаются, но похоже, что LINQ to SQL может отправлять вставку без причины. Проверка свойства ChangeSet в базе данных показывает 1 удаление и отсутствие вставок.

Я использую следующий небольшой фрагмент кода для выполнения удаления:

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

Журналов в MySql показывает следующие команды выполняются, когда это выполняется:

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

Что может привести к это ненужно INSERT? Обратите внимание, что при удалении Manufacturer в точно таким же образом удаляются корректно, при следующем журнале:

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

Edit: После дальнейшего тестирования, кажется, что это происходит только после того, как я заселена в ListBox со списком ProbeDefinition s.

Я попытался запустить выше удаления кода до и после того, как следующий фрагмент был бежать:

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

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

объект удаляется правильно, прежде чем сказал код запуска, но в любое время после этого момента, она выполняет вставку после того, как Удалить. Не нравится ли это тому, что объект упоминается где-то?

Вот код, я бег, чтобы проверить удаление определения из промежуточного окна:

database.ProbeDefinition.DeleteOnSubmit(database.ProbeDefinition.Last()) 
database.SubmitChanges() 
+0

Если другая таблица удаляется просто отлично, она, скорее всего, будет иметь какое-то отношение к вашим настройкам в таблице ProbeDefinition в дизайне LinqToSql. Можете ли вы предоставить эти настройки? –

+0

Я не использовал конструктор LinqToSql, а классы были сгенерированы с использованием DbMetal.exe, снабженного DbLinq, и я был подключен в коде. Оглядываясь на сгенерированные определения из DbMetal, я не вижу никакого кода, связанного с удалением ... –

+0

@NickLarsen: я обновил вопрос с некоторыми дополнительными выводами, в частности, что только после того, как существующие ссылки на объект удаляют также выполнить вставку. –

ответ

1

Оказывается, есть проблемы, когда есть несколько ссылок на ваш объект. Пройдя через источник DbLinq, я узнал, что после завершения DELETE он проходит через все остальные «наблюдаемые» объекты, ища ссылки.

В этом случае у меня есть несколько ссылок по таблице database.ProbeDefinition, а также по ссылке производителя, manufacturer.ProbeDefinition. Это не проблема, пока я не получил доступ к объектам с помощью обоих методов. Использование Remove может удалить ссылку от производителя, используя DeleteOnSubmit удалит объект из таблицы. Если я делаю то или другое, другая ссылка все еще существует, и, таким образом, объект помечен как повторно вставленный. Я не уверен, что это ошибка в DbLinq, что она не удаляет другие ссылки или ожидаемое поведение.

В любом случае, в моем случае решением является либо доступ к таблице с использованием только одного метода, либо удаление с использованием этого метода, либо удаление с использованием обоих методов.Ради, чтобы это работало, я использовал второй метод:

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

EDIT: При дальнейшей работе над проектом и аналогичные вопросы, я нашел истинную основной вопрос моей реализации. У меня долгоживущий DataContext, и как работает кеширование (чтобы сделать работу SubmitChanges), вы не можете этого сделать. Решение real должно иметь краткосрочный DataContext и повторно подключаться к базе данных в каждом методе.