Каскадные удаления не сохраняются в базе данных в моем типизированном наборе данных

Типизированные наборы данных в ADO.Net должны иметь возможность каскадного удаления и обновления, когда DataRelation устанавливается между двумя таблицами, скажем, родительской и дочерней. Однако я не смог заставить это работать. Я должен уточнить: у меня это работает в памяти; но он не сохраняется в базе данных.

Я создал тестовый проект с двумя таблицами в базе данных: Colors и Boxes. У каждого есть первичный ключ идентификатора и имя (например, «BoxId, BoxName»). Colors является родителем, а Boxes также имеет поле ColorId, помеченное ограничением внешнего ключа. Затем я настроил Winform с двумя DataGridView, по одному для каждой таблицы. Я перетащил две таблицы в новый набор данных, и их взаимосвязь появилась в дизайнере. Я отредактировал отношение как «И внешний ключ, и отношение», и установил для всех трех параметров ссылочной целостности значение «Каскад» (т.е. DeleteRule, UpdateRule, AcceptRejectChanges). Я также создал DeleteCommand для таблицы Boxes, потому что дизайнер почему-то отказался это делать. Наконец, я помещаю кнопку рядом с каждой сеткой для сохранения и помещаю вызов Update() в обработчик событий для каждого (например, this.boxesTableAdapter.Update(this.pOCDataSet.Boxes);)

Когда я запускаю форму и SQL Profiler, я вижу все свои данные и могу без проблем удалять элементы в дочерних элементах (коробках). Эти удаления также генерируют DELETE в базе данных. Отлично.

Когда я выполняю удаление в верхней сетке (Цвета), удаленная строка исчезает, и строки в сетке «Ящики» также исчезают (при условии, что я НЕ ПРОВЕРЯЮ ограничение FK в базе данных). Это выглядит великолепно. Однако в профилировщике явно выполнялась только инструкция Colors DELETE. Строки Boxes потеряны. Вы не увидите этого в Winform, если не перезапустите приложение, и в этот момент потенциальные удаленные строки в полях появятся с красным восклицательным значком слева от них, что указывает на то, что они нарушают ограничение FK.

Это сводит с ума, потому что кажется, что мой единственный вариант здесь - это самостоятельно закодировать материал ссылочной целостности, а-ля использовать сохраненный процесс для выполнения удаления цветов (внутри которого я также выполнял бы удаление ящиков) или заказ ON DELETE CASCADE на SQL Server или даже удаление встроенных блоков в операторе удаления Colors. Я постоянно возвращаюсь к тому факту, что объект DataRelation в моей модели должен обрабатывать это за меня. Ясно, что объекты BindingSource получают это, поскольку они удаляют соответствующие строки из дочерней сетки. Но почему модель сначала не выполняет Delete для таблицы Boxes, а затем для таблицы Colors?


person Mike K    schedule 27.04.2011    source источник


Ответы (1)


Удаление строк в наборе данных только пометит их для удаления в вашем наборе данных; вам все равно придется использовать адаптер таблицы для каждой таблицы в БД, из которой вы хотите удалить данные. Вы можете думать о наборе данных как о своей версии базы данных в памяти. Эти изменения необходимо зафиксировать в базе данных в правильном порядке, чтобы предотвратить ошибки FK. В вашем случае вам нужно запустить оператор обновления для родительской таблицы (цвета) ПОСЛЕ того, как все удаления для дочерних элементов (ящиков) были совершены так...

this.boxesTableAdapter.Update(this.pOCDataSet.Boxes);
this.colorsTableAdapter.Update(this.pOCDataSet.Colors);

Надеюсь это поможет.

person Carter Medlin    schedule 17.10.2011