C# ADO.NET каскадное удаление записей
От: Nike85  
Дата: 18.01.08 10:51
Оценка:
Здравствуйте!

Пишу первое приложение на C#. Появилась загвоздка при удалении записи из БД.
Структура БД — таблица Machines (машины) и таблица Services (обслуживания).
Machines:
ID — уникальный ключ
Name — название


Services
ID — уникальный ключ
Date — дата
Description — описание
IDMachine — код машины

Таблицы связаны — Machines.ID -> Services.IDMachine (один ко многим). Хочу, чтобы при удалении записи из Machines автоматом удалялись и дочерние записи в Services. Уже перепробовал разные варианты, однако добиться каскадного удаления не получается.
Ниже код реализации:



....
// подготовка данных
            eLibraDataSet.Relations.Add("Machines_Services", eLibraDataSet.Machines.IDColumn,
                eLibraDataSet.Services.IDMachineColumn,false);
           
            fkc = new ForeignKeyConstraint("Machines_ServicesFK",
                eLibraDataSet.Machines.IDColumn, eLibraDataSet.Services.IDMachineColumn);
            fkc.DeleteRule = Rule.Cascade;
            fkc.UpdateRule = Rule.SetNull;
            eLibraDataSet.Machines.Constraints.Add(fkc);
            eLibraDataSet.EnforceConstraints = false; //это ограничение включаю непосредственно перед удалением, поэтому пока отключаю его

            machinesTableAdapter.Fill(eLibraDataSet.Machines);
            servicesTableAdapter.Fill(eLibraDataSet.Services);
....
// непоcредственно удаление

                    eLibraDataSet.EnforceConstraints = true;
                    machinesTableAdapter.Delete(0);  //удаляю первую запись в главной таблице, для нее есть записи в подчиненной
                    eLibraDataSet.EnforceConstraints = false;
                    machinesTableAdapter.Update(eLibraDataSet.Machines); // но после обновления в подчиненной записи остаются на месте
                    servicesTableAdapter.Update(eLibraDataSet.Services);
                    machinesTableAdapter.Fill(eLibraDataSet.Machines);
                    servicesTableAdapter.Fill(eLibraDataSet.Services);
...


Не выходит у меня таким образом каскадно удалять записи. Из главной таблицы удаляется запись, а подчиненные записи остаются.
Может кто-нибудь подскажет, каким образом надо организовать это удаление?
Re: C# ADO.NET каскадное удаление записей
От: frik  
Дата: 18.01.08 12:40
Оценка:
Здравствуйте, Nike85, Вы писали:

а почему бы не реализовать это удаление на уровне базы данных?
Re[2]: C# ADO.NET каскадное удаление записей
От: Nike85  
Дата: 18.01.08 13:51
Оценка:
Здравствуйте, frik, Вы писали:

F>Здравствуйте, Nike85, Вы писали:


F>а почему бы не реализовать это удаление на уровне базы данных?


Хотелось бы сделать это в программе, средством шарпа. Если честно, не знаю, поддерживает ли MS Access (использую эту БД) триггеры, чтобы реализовать каскадное удаление в самой программе. Кажется, нет.
Но даже если поддерживает, хотелось иметь возможность включать/отключать контроль за удалением записей. Можно, конечно, устроить дебаты, как лучше в данном случае поступить — реализовывать данную возможность на уровне БД или приложения. С радостью выслушаю дводы за и против. Однак сейчас мне важнее разобраться почему этот код не работает и как его заставить работать
Re[3]: C# ADO.NET каскадное удаление записей
От: frik  
Дата: 18.01.08 13:53
Оценка:
Здравствуйте, Nike85, Вы писали:

N>Здравствуйте, frik, Вы писали:


F>>Здравствуйте, Nike85, Вы писали:


F>>а почему бы не реализовать это удаление на уровне базы данных?


N>Хотелось бы сделать это в программе, средством шарпа. Если честно, не знаю, поддерживает ли MS Access (использую эту БД) триггеры, чтобы реализовать каскадное удаление в самой программе. Кажется, нет.

N>Но даже если поддерживает, хотелось иметь возможность включать/отключать контроль за удалением записей. Можно, конечно, устроить дебаты, как лучше в данном случае поступить — реализовывать данную возможность на уровне БД или приложения. С радостью выслушаю дводы за и против. Однак сейчас мне важнее разобраться почему этот код не работает и как его заставить работать

конечно поддерживает. думаю любая БД такое поддерживает, это типа целостоность БД, если нет родительской записи то и не должно быть зависящих от нее записей
Re[4]: C# ADO.NET каскадное удаление записей
От: Lloyd Россия  
Дата: 18.01.08 14:03
Оценка:
Здравствуйте, frik, Вы писали:

N>>Хотелось бы сделать это в программе, средством шарпа. Если честно, не знаю, поддерживает ли MS Access (использую эту БД) триггеры, чтобы реализовать каскадное удаление в самой программе. Кажется, нет.


F>конечно поддерживает. думаю любая БД такое поддерживает, это типа целостоность БД, если нет родительской записи то и не должно быть зависящих от нее записей


триггеры?
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[5]: C# ADO.NET каскадное удаление записей
От: frik  
Дата: 18.01.08 14:09
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, frik, Вы писали:


N>>>Хотелось бы сделать это в программе, средством шарпа. Если честно, не знаю, поддерживает ли MS Access (использую эту БД) триггеры, чтобы реализовать каскадное удаление в самой программе. Кажется, нет.


F>>конечно поддерживает. думаю любая БД такое поддерживает, это типа целостоность БД, если нет родительской записи то и не должно быть зависящих от нее записей


L>триггеры?


ээ так каскадное удаление это не триггеры, я про каскадное удаление писал
Re[2]: C# ADO.NET каскадное удаление записей
От: Nike85  
Дата: 19.01.08 03:01
Оценка:
Здравствуйте, frik, Вы писали:

F>Здравствуйте, Nike85, Вы писали:


F>а почему бы не реализовать это удаление на уровне базы данных?


И все же, как реализовать это с помощью C#? Зачем тогда в режиме дизайнера Dataset'а в Visual Studio можно добавлять связи между таблицами, устанавливать внешние ключи, указывая для них правила, срабатывющие в том числе и на удаление записей?
Re[3]: C# ADO.NET каскадное удаление записей
От: Аноним  
Дата: 19.01.08 03:35
Оценка: -1
Здравствуйте, Nike85, Вы писали:

N>Здравствуйте, frik, Вы писали:


F>>Здравствуйте, Nike85, Вы писали:


F>>а почему бы не реализовать это удаление на уровне базы данных?


N>И все же, как реализовать это с помощью C#? Зачем тогда в режиме дизайнера Dataset'а в Visual Studio можно добавлять связи между таблицами, устанавливать внешние ключи, указывая для них правила, срабатывющие в том числе и на удаление записей?


Dataset нужен для создания полного снимка БД, соответственно он должен повторить структуру бд
Re[4]: C# ADO.NET каскадное удаление записей
От: Nike85  
Дата: 19.01.08 04:08
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Nike85, Вы писали:


N>>Здравствуйте, frik, Вы писали:


F>>>Здравствуйте, Nike85, Вы писали:


F>>>а почему бы не реализовать это удаление на уровне базы данных?


N>>И все же, как реализовать это с помощью C#? Зачем тогда в режиме дизайнера Dataset'а в Visual Studio можно добавлять связи между таблицами, устанавливать внешние ключи, указывая для них правила, срабатывющие в том числе и на удаление записей?


А>Dataset нужен для создания полного снимка БД, соответственно он должен повторить структуру бд


Да, в самой БД я не прописал связи и правила при удалении записей. Но почему, если в я создаю динамически во время выполнения Relation между таблицами, то программа ругается на отсутствие связанных записей в главной таблице (т.е. механизм связей работает), а при удалении записи в главной таблице не срабатывает каскадное удаление в дочерней?
Re[5]: C# ADO.NET каскадное удаление записей
От: Аноним  
Дата: 19.01.08 04:18
Оценка: -1
Здравствуйте, Nike85, Вы писали:


N>Да, в самой БД я не прописал связи и правила при удалении записей. Но почему, если в я создаю динамически во время выполнения Relation между таблицами, то программа ругается на отсутствие связанных записей в главной таблице (т.е. механизм связей работает), а при удалении записи в главной таблице не срабатывает каскадное удаление в дочерней?


по поводу ругания могу сказать -читай документацию. а вобще зачем этот лишний геморой- не проще ли все зависимости прописать в БД, и пусть бд сама следит. это ее работа
Re[6]: C# ADO.NET каскадное удаление записей
От: Nike85  
Дата: 19.01.08 04:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Nike85, Вы писали:



N>>Да, в самой БД я не прописал связи и правила при удалении записей. Но почему, если в я создаю динамически во время выполнения Relation между таблицами, то программа ругается на отсутствие связанных записей в главной таблице (т.е. механизм связей работает), а при удалении записи в главной таблице не срабатывает каскадное удаление в дочерней?


А>по поводу ругания могу сказать -читай документацию. а вобще зачем этот лишний геморой- не проще ли все зависимости прописать в БД, и пусть бд сама следит. это ее работа


Ругание то очевидно, из-за чего происходит, т.к. не выполняются связи (к примеру, при открытой дочерней таблице и закрытой родительской). Не понятно, почему шарп также основательно не выполняет свои обязательства fkc.DeleteRule = Rule.Cascade.
Попробую в самой аксессовской БД прописать ограничения, может это меня и устроит. НО все равно, почему шарп не делает этого сам???
Re: C# ADO.NET каскадное удаление записей
От: Lloyd Россия  
Дата: 19.01.08 13:18
Оценка:
Здравствуйте, Nike85, Вы писали:

N>Не выходит у меня таким образом каскадно удалять записи. Из главной таблицы удаляется запись, а подчиненные записи остаются.

N>Может кто-нибудь подскажет, каким образом надо организовать это удаление?

Замени
machinesTableAdapter.Delete(0);

на
eLibraDataSet.Machines[0].Delete();
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[2]: C# ADO.NET каскадное удаление записей
От: __kain Россия  
Дата: 19.01.08 14:41
Оценка:
Советую почитать книгу ADO.NET Девида Сеппа. Там очень толково все описано. Конкретно твой случай — глава "Сложные случаи обновления данных". Редакция книги не важна — там мало изменений, ИМХО.

Если нужно будет — напишу пример кода... Когда делал курсовой, у меня нормально удалялись записи (по примерам книги).
Re[3]: C# ADO.NET каскадное удаление записей
От: Lloyd Россия  
Дата: 19.01.08 18:12
Оценка: :)
Здравствуйте, __kain, Вы писали:

__>Советую почитать книгу ADO.NET Девида Сеппа.


Мне?
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re: C# ADO.NET каскадное удаление записей
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.01.08 07:21
Оценка:
Здравствуйте, Nike85, Вы писали:

N> Хочу, чтобы при удалении записи из Machines автоматом удалялись и дочерние записи в Services.


А ты случаем не перепутал таблицу, к которой ты FK добавляешь? Это во-первых. А во-вторых у FK нужно еще инициализировать свойство AcceptRejectRules. По умолчанию оно равно None.
... << RSDN@Home 1.2.0 alpha rev. 725 on Windows Vista 6.0.6000.0>>
AVK Blog
Re: C# ADO.NET каскадное удаление записей
От: Poul_Ko Казахстан  
Дата: 21.01.08 04:15
Оценка:
Здравствуйте, Nike85, Вы писали:

N>Таблицы связаны — Machines.ID -> Services.IDMachine (один ко многим). Хочу, чтобы при удалении записи из Machines автоматом удалялись и дочерние записи в Services. Уже перепробовал разные варианты, однако добиться каскадного удаления не получается.


Давайте опишу, как всё должно работать. Можете воспользоваться отладкой и найти, где идёт не так.
0. Имеются две таблицы, между ними связь 1-ко-многим, во второй таблице внешний ключ. Настройки внешнего ключа: DeleteRule=Cascade, AcceptRejectRule=None.
1. Constraint'ы включены. Удаляем запись в главной таблице — запись переходит в состояние Deleted, связанные записи в дочерней таблице так же переходят в состояние Deleted — в соответствии с правилом DeleteRule=Cascade
2. Выключаем constraint'ы. Обновляем записи из главной таблицы — запись удаляется из БД, в DataTable ей делается Commit и она удаляется из таблицы. Дочерние записи не затрагиваются (они так и остаются в состоянии Deleted) благодаря тому, что AcceptRejectRule=None
3. Обновляем записи дочерней таблицы — Deleted записи удаляются из БД и из DataTable.

Попробуйте поотлаживать простейшие случаи, обратите внимание на состояние (свойство RowState) записей.
Brainbench transcript #6370594
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.