C#检测外键冲突的代码

简介:

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

假设有一张产品类别表: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

对引入外键的表的描述

代码的实现:

namespace DTMS.DAL.Components.Common { /// <summary> /// 数据访问层——在删除之前检查是否存在外键约束(辅助类) /// </summary> public static class CheckFKReferences { /// <summary> /// 检查是否存在外键约束 /// </summary> /// <param name="id">要删除记录的主键</param> /// <param name="primaryTable">记录所在的表</param> public static string CheckFKBeforeDelete(string id, string primaryTable) { try { string errText = ""; //连接字符串 string connString = ConfigurationManager.ConnectionStrings["DTMS_DBConnectionString"].ConnectionString; DTMS.DTMS_LINQDataContext db = new DTMS_LINQDataContext(); //取得当前表的所有外键信息 var fts = db.Sys_PrimaryForeignTables.Where(pt => pt.primaryTables.Trim() == primaryTable).ToList(); string fId, fTable, strSQL; string[] sql, sqlArray; int count = 0; for (int i = 0; i < fts.Count; i++) { fId = fts[i].foreginId.Trim(); fTable = fts[i].foreignTables.Trim(); sql = new string[]{ "SELECT COUNT(*) FROM ", fTable, " WHERE ", fId, "='", id, "'" }; strSQL = string.Concat(sql); count = Convert.ToInt32(DTMS.DAL.DBUtility.SqlHelper.ExecuteScalar(connString, System.Data.CommandType.Text, strSQL_1)); if (count > 0) { sqlArray = new string[]{ "在删除[",fts[i].primaryRemark.Trim(),"]中的记录时,由于外键约束,所以该记录暂时无法删除。", "请确保将先[",fts[i].foreignRemark.Trim(),"]中关联的相关记录删除后,再执行此删除操作!"}; errText = string.Concat(sqlArray); LogTools.Instance.Log(errText); return errText; } } return ""; } catch (Exception ex) { throw ex; } } } }

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




原文发布时间为:2010-06-15


本文作者:vinoYang


本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。

目录
相关文章
|
7月前
|
C# Windows
C#通过代码实现快捷键编辑
C#通过代码实现快捷键编辑
|
2月前
|
缓存 C# Windows
C#程序如何编译成Native代码
【10月更文挑战第15天】在C#中,可以通过.NET Native和第三方工具(如Ngen.exe)将程序编译成Native代码,以提升性能和启动速度。.NET Native适用于UWP应用,而Ngen.exe则通过预编译托管程序集为本地机器代码来加速启动。不过,这些方法也可能增加编译时间和部署复杂度。
150 2
|
4月前
|
C# 开发者 Windows
在VB.NET项目中使用C#编写的代码
在VB.NET项目中使用C#编写的代码
62 0
|
2月前
|
C#
C# 图形验证码实现登录校验代码
C# 图形验证码实现登录校验代码
89 2
|
2月前
|
中间件 数据库连接 API
C#数据分表核心代码
C#数据分表核心代码
42 0
|
4月前
|
物联网 C# Windows
看看如何使用 C# 代码让 MQTT 进行完美通信
看看如何使用 C# 代码让 MQTT 进行完美通信
636 0
|
4月前
|
数据安全/隐私保护 C# UED
利用 Xamarin 开展企业级移动应用开发:从用户登录到客户管理,全面演示C#与Xamarin.Forms构建跨平台CRM应用的实战技巧与代码示例
【8月更文挑战第31天】利用 Xamarin 进行企业级移动应用开发能显著提升效率并确保高质量和高性能。Xamarin 的跨平台特性使得开发者可以通过单一的 C# 代码库构建 iOS、Android 和 Windows 应用,帮助企业快速推出产品并保持一致的用户体验。本文通过一个简单的 CRM 示例应用演示 Xamarin 的使用方法,并提供了具体的代码示例。该应用包括用户登录、客户列表显示和添加新客户等功能。此外,还介绍了如何增强应用的安全性、数据持久化、性能优化及可扩展性,从而构建出功能全面且体验良好的移动应用。
57 0
|
4月前
|
前端开发 开发者 Apache
揭秘Apache Wicket项目结构:如何打造Web应用的钢铁长城,告别混乱代码!
【8月更文挑战第31天】Apache Wicket凭借其组件化设计深受Java Web开发者青睐。本文详细解析了Wicket项目结构,帮助你构建可维护的大型Web应用。通过示例展示了如何使用Maven管理依赖,并组织页面、组件及业务逻辑,确保代码清晰易懂。Wicket提供的页面继承、组件重用等功能进一步增强了项目的可维护性和扩展性。掌握这些技巧,能够显著提升开发效率,构建更稳定的Web应用。
113 0
|
4月前
|
前端开发 程序员 API
从后端到前端的无缝切换:一名C#程序员如何借助Blazor技术实现全栈开发的梦想——深入解析Blazor框架下的Web应用构建之旅,附带实战代码示例与项目配置技巧揭露
【8月更文挑战第31天】本文通过详细步骤和代码示例,介绍了如何利用 Blazor 构建全栈 Web 应用。从创建新的 Blazor WebAssembly 项目开始,逐步演示了前后端分离的服务架构设计,包括 REST API 的设置及 Blazor 组件的数据展示。通过整合前后端逻辑,C# 开发者能够在统一环境中实现高效且一致的全栈开发。Blazor 的引入不仅简化了 Web 应用开发流程,还为习惯于后端开发的程序员提供了进入前端世界的桥梁。
467 0
|
4月前
|
C#
C# 跳过值班时间代码逻辑
C# 跳过值班时间代码逻辑
35 0