C#检测外键冲突的代码

时间:2022-10-07 15:19:45

大家都明白,在设计数据库的时候,外键的存在无可避免。在带来好处的同时(确保数据的完整性和一致性等,这些都不多说了),也有它的很多缺陷,那就是使诸如查询等相关操作的效率降低(但有的时候这也是没办法的事情,现在硬件发展都这么快了),但最主要的是,某些时候,在用户不知道各个实体关系的情况下,他们想去删某些记录,下面我们举个例子。

 

假设有一张产品类别表:Categary,一张产品表Product,其中产品表引用类表表中的类别编号作为外键。

 

如果出现这样一种情况,一个用户拥有这些表的删除权限,假设他拥有最高权限,也许此时考虑到数据一致性,你不会开放给用户Categary表记录的删除权限,但假设确实有这么种情况,这种产品类别的产品我们以后确实不会在这个系统中使用,也就是某种产品类别的存在没有意义。因此从可维护性的角度来讲,我们需要将这条记录删除是符合业务逻辑需要的。

 

但如果开放给用户权限吧,用户删除Categary中被Product表中记录引为外键的记录,会出现很多情况:代码不严谨,直接报错抛给用户,很悲剧;严谨点,捕获到异常,但只是告诉用户出错,这是通常的做法,但用户觉得很莫名其妙。如果Categary类别表中确实有垃圾记录,或者用户想删某条记录。我们需要在有外键约束冲突的情况下,给用户更友好的提示信息,或者提醒他,应该先删什么表中的什么数据,然后才能删这条记录等等。

 

下面是实现:

在项目数据库中增加一张表,该表有数据库管理员维护,此表是项目中其他表之间主外键关系的描述,我们不能直接告诉用户真实的主、外键表(出于安全),但我们可以告诉他们关于这些表功能的描述,让他们知道哪里有冲突,为什么不能删这条记录等等

表名:Sys_PrimaryForeignTables(系统主外键关系表)

字段名

类型

描述

id

Int PK not null

自增编号

primaryTables

Nvarchar(50) not null

主表(如部门表)

foreignTables

Nvarchar(50) not null

引入外键表(如学生表)

foreginId

Nvarchar(20) not null

外键表中的外键字段名

primaryRemark

Nvarchar(255) null

对主表的描述

foreignRemark

Nvarchar(255) null

对引入外键的表的描述

 

 

 

 

代码的实现:

 

实现很简单,相信你能看得懂,一般情况下,在DAL中,我们在对那些有键作为其他表的外键的表作删除的时候,会先去检查。当然,你也可以为此抽象出一个IDeleteable接口,让每个DAL中有删除操作的业务类去实现这个接口。