При удалении записи, на которую есть ссылки в другой таблице, как узнать, когда следует остановиться? - PullRequest
3 голосов
/ 22 июля 2010

В моей базе данных есть следующая структура таблицы:

create table Encargado(
ID int primary key,
Nombre varchar(300),
)

create table Area(
ID int primary key,
Nombre varchar(300),
Jefe int foreign key references Encargado(ID)
)

create table Carrera(
ID int primary key,
Nombre varchar(300),
Area int foreign key references Area(ID)
)

create table Formacion(
ID int primary key,
Grado varchar(300),
Lugar varchar(300)
)

create table Docente(
ID int primary key,
Nombre varchar(300),
Carrera int foreign key references Carrera(ID),
Formacion int foreign key references Formacion(ID),
Horario varchar(300)
)

create table Evaluacion(
ID int primary key,
Docente int foreign key references Docente(ID),
Evaluador varchar(300),
Secuencia int,
Pizarra int,
Audiovisual int,
Letra int,
Voz int,
GestosVocabulario int,
Ejemplificacion int,
Respuestas int,
DominioEscenico int,
Participacion int,
Observacion varchar(4000),
Materias varchar(3000),
Valido bit
)

create table Seguimiento(
ID int primary key,
Docente int foreign key references Docente(ID),
Modulo int,
Semestre int,
Ano int,
Fecha datetime,
Hora datetime,
OrdenSecuencia bit,
OrdenSecuenciaObservacion varchar(200),
PortafolioAlumno bit,
PortalofioAlumnoObservacion varchar(200),
AspectosParaEntrevista varchar(3000),
Conclusiones varchar(3000),
Evaluador varchar(300),
DirectorDeArea int foreign key references Encargado(ID),
EncargadoControl int foreign key references Encargado(ID),
)

Скажите, что я хочу удалить область, как бы я это сделал? Мне также нужно удалить все Карреры, а также всех доцентов.

public void Delete(Area area)
        {
            db.Carreras.DeleteAllOnSubmit(area.Carreras);
            //I'm stuck here. Is this what I should be doing?
        }

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

Я использую C # и Linq-to-SQL. Я чувствую, что, возможно, закопался в яму с помощью этой структуры таблиц или, может быть, это один из недостатков реляционной базы данных? : \

Ответы [ 4 ]

2 голосов
/ 22 июля 2010

Я бы не стал обрабатывать это на стороне Linq-to-SQL, я бы использовал каскадное удаление на стороне базы данных, если вы действительно хотите удалить все дочерние записи.

Например, в Oracle вы можете добавить предложение «ON DELETE CASCADE» в свои операторы создания таблиц, см. эту ссылку.

Каскадное удаление будет обрабатывать удаление всех записей из дочерних таблиц, все с одной операцией удаления. Прелесть этого подхода в том, что независимо от того, где вы выполняете операцию, хотя и через Linq-To-SQL, JAVA, ROR, PHP и т. Д., Логика централизована в БД, поэтому она работает одинаково независимо от того, кто выполняет удаление .

1 голос
/ 22 июля 2010

Это должно зависеть от того, как вы хотите обрабатывать отношения с внешним ключом. т.е. удаление иностранных ссылок или оставление их в случае, если от них зависят другие записи и т. д.

См. Ссылочную целостность http://msdn.microsoft.com/en-us/library/ms186973.aspx

Итак, в конце концов, вы, вероятно, должны позволить БД справиться с этим.

0 голосов
/ 22 июля 2010

Рассматривали ли вы «логическое удаление» вместо физического удаления?

Логическое удаление имеет смысл, если вы хотите сохранить исторический доступ к данным (для отчетов или запросов) даже после того, как они устарели.

Пример: ваша школа раньше преподавала латынь, и в ней обучалось несколько преподавателей, а также обучалось несколько студентов.В следующем году латынь будет удалена из доступных курсов.Один из профессоров уходит в отставку, остальные продолжают другие курсы.Студентам все еще нужно доказать, что они получили голос на латыни, даже если это не будет частью будущих предложений.

Решение: добавьте логический флаг в таблицу курса (Active = Y / N) и адаптируйте свою программутак что он исключает курсы (или профессоров, или что-либо еще), имеющие "Active = N" из запросов, которые должны возвращать то, что является "живым", и сохранять их для исторических отчетов.

0 голосов
/ 22 июля 2010

Скажите, что я хочу удалить область, как я бы сделал это? Мне бы тоже нужно удалить все Carreras, а также все Docentes.

На первый взгляд кажется, что вы хотите изменить действие декларативной ссылочной целостности (DRI) для ON DELETE со значения по умолчанию NO ACTION (т.е. предотвратить удаление указанной строки) на CASCADE (т.е. также удалить строки в справочной таблице).

Обратите внимание, что такая логика обычно предполагает, что ссылочный столбец (например, Carrera.Area) должен быть определен как NOT NULL.

Например:

CREATE TABLE Carrera
(
...
Area INTEGER NOT NULL
   REFERENCES Area (ID) 
   ON DELETE CASCADE
);

CREATE TABLE Docente
(
...
Carrera INTEGER NOT NULL
   REFERENCES Carrera (ID)
   ON DELETE CASCADE, 
...
);

Однако, посмотрев глубже, мы увидим, что

Evaluacion REFERENCES Docente
Seguimiento REFERENCES Docente

Вам необходимо решить, требуют ли они действия ON DELETE CASCADE DRI.

* * 1 022 Кроме того:
Seguimiento REFERENCES Encargado -- twice
Area REFERENCES Encargado

Другими словами, у вас есть потенциальный цикл здесь. Даже если ваша СУБД будет разрешать ON DELETE CASCADE действия DRI для всех этих функций (например, SQL Server не будет), вам следует рассмотреть возможность управления логикой путем «ручного» удаления строк.

Что-то еще, чтобы рассмотреть, видя все эти, казалось бы, NULLable столбцы (но как столбцы первичного ключа могут быть обнуляемыми ...?) Вы можете рассмотреть действие ON DELETE SET NULL DRI. Лично я хотел бы прояснить дизайн, удалив столбцы NULL, создающие новые таблицы взаимосвязей, но это может потребовать много работы:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...