C# 删除带有外键引用约束的行时的用户友好错误消息
处理删除具有FK引用约束的db行的最佳实践是什么?我的目标是向最终用户提供更友好的错误消息。请注意,我不想删除有员工的部门,也不想对表进行级联删除 例如,如果我们有两个表:C# 删除带有外键引用约束的行时的用户友好错误消息,c#,.net,sql,validation,ado.net,C#,.net,Sql,Validation,Ado.net,处理删除具有FK引用约束的db行的最佳实践是什么?我的目标是向最终用户提供更友好的错误消息。请注意,我不想删除有员工的部门,也不想对表进行级联删除 例如,如果我们有两个表: -- Department table CREATE TABLE [dbo].[Department]( [Id] [int] IDENTITY(1,1) NOT NULL, [Name] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
-- Department table
CREATE TABLE [dbo].[Department](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
-- Employee table
CREATE TABLE [dbo].[Employee](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[DepartmentId] [int] NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [FK_Employee_Department] FOREIGN KEY([DepartmentId])
REFERENCES [dbo].[Department] ([Id])
GO
ALTER TABLE [dbo].[Employee] CHECK CONSTRAINT [FK_Employee_Department]
若要从department表中删除行,则该行在employee表中引用。该怎么办
catch (SqlException ex)
{
switch (ex.Number)
case 547: HandleErrorGracefully()
}
如果有人有应用程序示例的代码/链接,那就太好了…选项3:同时执行1和2 有可能有人在检查(通过)和删除失败之间插入另一个进程
在这种情况下,您可以对用户说“对不起,出了问题”(但要记录),然后看看他们是否想再试一次。然后检查将截取它。选项3:同时执行1和2 有可能有人在检查(通过)和删除失败之间插入另一个进程
在这种情况下,您可以对用户说“对不起,出了问题”(但要记录),然后看看他们是否想再试一次。然后检查将拦截它。@gbn的答案是一个很好的方法。但是,您也可以在外键关系的DELETE CASCADE上设置
,并询问用户类似“您确定要删除此部门及其所有员工吗?”。@gbn的回答是一个很好的方法。但是,您也可以在外键关系的DELETE CASCADE上放置,并询问用户类似“您确定要删除此部门及其所有员工吗?”。友好点
显示其中的部门和员工人数,仅当员工人数为0时才启用删除选项
依靠引用完整性来停止编码错误,而不是用户错误…更好
显示其中的部门和员工人数,仅当员工人数为0时才启用删除选项
依靠引用完整性来停止编码错误,而不是用户错误…几天前/几个月前,我也遇到过同样的问题。经过大量的谷歌搜索,我终于解决了使用SqlHelper类在DAL中翻译错误消息的问题
我用以下方法处理这个问题
创建了一些从Exception类派生的类,如中所示
在SqlHelper中
public void ExecuteNonQuery(string procedure)
{
try
{
con.open()
cmd.executenonquery();
con.close();
//Sql Exception is raised
}
catch(SqlException ex)
{
throw TranslateException(ex);
}
}
使用链接中的代码,我将Sql异常转换为DaleException,而不是Exception
protected DalException TranslateException(SqlException ex) {
DalException dalException = null;
// Return the first Custom exception thrown by a RAISERROR
foreach (SqlError error in ex.Errors) {
if (error.Number >= 50000) {
dalException = new DalException(error.Message, ex);
}
}
if (dalException == null) {
// uses SQLServer 2000 ErrorCodes
switch (ex.Number) {
case 2601:
// Unique Index/Constriant Violation
dalException = new DalUniqueConstraintException("{0} failed, {1} must be unique", ex);
break;
default:
// throw a general DAL Exception
dalException = new DalException(ex.Message, ex);
break;
}
}
// return the error
return dalException;
}
请注意案例2601:
我在这里发送了自定义消息
现在在我的DAL中,我将只处理DaleException,它将返回异常消息作为
“{0}失败,{1}必须是唯一的”,使用string.Format(msg,
“插入”、“客户”)
这将向BAL发送一个异常,即“插入失败,客户端必须唯一”,这可能是一条一般性消息
编辑
这将在DAL as处理
public Client Insert()
{
try
{
_repository.Insert(client);
}
catch(DalException ex)
{
//wrap message since, error will always be in client entity as client's method is being called. Also, insertion is being failed.
throw new BusinessException(string.Format(ex.message), "Insertion", "Client");
}
}
参考资料
几天前/几个月前,我也有同样的问题。经过大量的谷歌搜索,我终于解决了使用SqlHelper类在DAL中翻译错误消息的问题
我用以下方法处理这个问题
创建了一些从Exception类派生的类,如中所示
在SqlHelper中
public void ExecuteNonQuery(string procedure)
{
try
{
con.open()
cmd.executenonquery();
con.close();
//Sql Exception is raised
}
catch(SqlException ex)
{
throw TranslateException(ex);
}
}
使用链接中的代码,我将Sql异常转换为DaleException,而不是Exception
protected DalException TranslateException(SqlException ex) {
DalException dalException = null;
// Return the first Custom exception thrown by a RAISERROR
foreach (SqlError error in ex.Errors) {
if (error.Number >= 50000) {
dalException = new DalException(error.Message, ex);
}
}
if (dalException == null) {
// uses SQLServer 2000 ErrorCodes
switch (ex.Number) {
case 2601:
// Unique Index/Constriant Violation
dalException = new DalUniqueConstraintException("{0} failed, {1} must be unique", ex);
break;
default:
// throw a general DAL Exception
dalException = new DalException(ex.Message, ex);
break;
}
}
// return the error
return dalException;
}
请注意案例2601:
我在这里发送了自定义消息
现在在我的DAL中,我将只处理DaleException,它将返回异常消息作为
“{0}失败,{1}必须是唯一的”,使用string.Format(msg,
“插入”、“客户”)
这将向BAL发送一个异常,即“插入失败,客户端必须唯一”,这可能是一条一般性消息
编辑
这将在DAL as处理
public Client Insert()
{
try
{
_repository.Insert(client);
}
catch(DalException ex)
{
//wrap message since, error will always be in client entity as client's method is being called. Also, insertion is being failed.
throw new BusinessException(string.Format(ex.message), "Insertion", "Client");
}
}
参考资料
可能重复可能重复抱歉,我没有写,但是,我不想删除有员工的部门,也不想对表进行级联删除。抱歉,我没有写,但是,我不想删除有员工的部门,也不想对表进行级联删除。可见的零计数可能已过期,因此删除将失败,需要进行检查(根据我的回答)“依赖引用完整性以停止编码错误”-不要依赖!将业务规则不正确地实现(或省略)到数据库约束中本身就是一个编码错误。@gbn。当然,它可能已经过时了。其他人可能已经删除了整个内容!这种可能性有多大?如果您已经改进了…@onedaywhen,如果我正在做一个db,那么是否值得花额外的代码来处理外键冲突呢。首先我做对了,然后我编码,如果在编码时我发现它不正确,我会停止,我会修复,我会重新测试,我会重新开始。我的方法是获得数据完整性,另一种方法是交叉手指。可见计数为零可能已过时,因此删除将失败,需要进行检查(根据我的回答)“依赖引用完整性停止编码错误”——不要依赖!将业务规则不正确地实现(或省略)到数据库约束中本身就是一个编码错误。@gbn。当然,它可能已经过时了。其他人可能已经删除了整个内容!这种可能性有多大?如果您已经改进了…@onedaywhen,如果我正在做一个db,那么是否值得花额外的代码来处理外键冲突呢。首先我做对了,然后我编码,如果在编码时我发现它不正确,我会停止,我会修复,我会重新测试,我会重新开始。我的方式