Объект повторно вставляется в базу данных сразу после удаления (DbLinq)

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

  •  23-09-2019
  •  | 
  •  

Вопрос

У меня есть база данных MySQL, общая структура которой выглядит следующим образом:

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

Я использую InnoDB для разрешения внешних ключей, и все внешние ключи, указывающие на ProbeDefinition установили ON DELETE CASCADE.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я удаляю ProbeDefinition в моем коде он немедленно вставляется повторно.Каскадное удаление происходит должным образом, поэтому другие таблицы очищаются, но, похоже, LINQ to SQL может отправлять insert без причины.Проверка свойства набора изменений в базе данных показывает 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 */ 

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

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

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()
Это было полезно?

Решение

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top