代码之家  ›  专栏  ›  技术社区  ›  Sergio Tapia

删除另一个表中引用的记录时,如何知道何时停止?

  •  3
  • Sergio Tapia  · 技术社区  · 14 年前

    我的数据库中有以下表结构:

    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 回复  |  直到 14 年前
        1
  •  2
  •   dcp    14 年前

    我不会在linqtosql端处理这个问题,如果您真的想删除所有子记录,我会在数据库端使用级联删除。

    例如,使用Oracle,您可以在create table语句中添加“ON DELETE CASCADE”子句,请参阅 this 链接。

    级联删除将处理从子表中删除所有记录的操作,所有操作都只需一次删除操作。这种方法的美妙之处在于,无论您在哪里执行操作(尽管是通过linqtosql、JAVA、ROR、PHP等),逻辑都集中在DB中,因此无论谁执行删除操作,其工作方式都是相同的。

        2
  •  1
  •   khai_khai    14 年前



    请参见引用完整性 http://msdn.microsoft.com/en-us/library/ms186973.aspx

    所以,最后你应该让DB来处理。

        3
  •  0
  •   onedaywhen    14 年前

    假设我要删除一个区域,如何删除 我会这么做吗?我也需要 删除所有carrera和所有

    表面上看,您似乎想要更改的声明性引用完整性(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操作。

    此外:

    Seguimiento REFERENCES Encargado -- twice
    Area REFERENCES Encargado
    

    DRI操作(例如,SQL Server不会)您应该考虑通过“手动”删除行来管理逻辑。

    另外要考虑的是,看到所有这些看起来可以为null的列(但是主键列怎么可能是可以为null的…?),您可以考虑 ON DELETE SET NULL DRI操作。就我个人而言,我会通过删除可为null的列来澄清设计,因为它们正在创建新的关系表,但这可能会涉及大量工作:)

        4
  •  0
  •   p.marino    14 年前

    当您希望保留对数据(用于报表或查询)的历史访问权限时,逻辑删除是有意义的,即使这些数据已过时。

    你们学校以前教拉丁语,有很多教授教,还有很多学生。

    解决方案:在Course表中添加一个布尔标志(Active=Y/N),并调整您的程序,以便将具有“Active=N”的课程(或教授,或任何其他内容)从必须返回“live”的查询中排除,并将其保留在历史报告中。