捕获特定异常
如何使用 C# 捕获特定异常?
在我的数据库中,某些列有唯一索引。
当用户插入重复记录时,会引发此异常:
无法插入重复的键行 具有唯一性的对象“dbo.BillIdentity” 索引“IX_BillIdentity”。这 声明已终止。
我怎样才能捕获这个异常?
目前我正在检查使用此代码:
catch (Exception ex) {
if (ex.Message.Contains("Cannot insert duplicate key row in object 'dbo._BillIdentity' with unique index 'IX__BillIdentity")) {
string ScriptKey = "$(function() {ShowMessage('Error');});";
ScriptManager.RegisterStartupScript(Page, GetType(), "script", ScriptKey, true);
}
}
我认为它的代码很难闻。
还有更好的办法吗?
How can I catch specific exception using c# ?
In my database there is unique index on some columns.
when user inserts duplicate record this exception has been throw :
Cannot insert duplicate key row in
object 'dbo.BillIdentity' with unique
index 'IX_BillIdentity'. The
statement has been terminated.
How can I catch this exception?
Currently I am checking using this code :
catch (Exception ex) {
if (ex.Message.Contains("Cannot insert duplicate key row in object 'dbo._BillIdentity' with unique index 'IX__BillIdentity")) {
string ScriptKey = "$(function() {ShowMessage('Error');});";
ScriptManager.RegisterStartupScript(Page, GetType(), "script", ScriptKey, true);
}
}
I think its bad smell code.
Is there any better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
仅在这种情况下处理
SqlException
。[编辑]
要检查 MS SQL Server 中的重复键异常:
编辑:
2601从哪里来?
返回:
使用
exception.Number
并引用 sys.messages 视图,您可以处理任何特定的 MS SQL 异常。Handle
SqlException
only in this case.[Edit]
To check duplicate key exception in MS SQL server:
Edit:
Where 2601 come from?
Returns:
Using
exception.Number
and referencing sys.messages view you can handle any specific MS SQL exception.您尚未显示引发的异常的类型,但您可以捕获该特定异常类型。例如:
只是此错误可能不会有特定的异常类型 - 但如果您必须捕获像
SqlException
这样相当普遍的东西,那么您可以寻找类本身的更多细节。例如,在SqlException
中,有一个Errors
属性,您可以在其中查看有关数据库端每个(可能是多个)错误的更详细信息。每个SqlError
然后有一个Number
属性将给出错误的类型。如果确实有必要,您可以随时返回该消息,但您需要意识到该消息可能会因不同文化等而发生变化。请注意,如果您没有真正处理异常,你可能应该重新抛出它:
You haven't shown the type of exception which is thrown, but you can catch that specific exception type. For example:
It's possible that there won't be a specific exception type for just this error - but if you have to catch something fairly general like
SqlException
you can then look for more details within the class itself. For example inSqlException
there's anErrors
property where you can look at more detailed information about each of the (possibly multiple) errors at the database side. EachSqlError
then has aNumber
property which will give the type of error. You can always fall back to the message if you absolutely have to, but you then need to be aware of the possibility of the message changing for different cultures etc.Note that if you're not really handling the exception, you should probably rethrow it:
我刚刚接手了一个项目,其中有人沿着这条路线走:
请注意以下内容(来自 SQL Server 中的 sys.messages):
2601 - 无法在具有唯一索引 '%.* 的对象 '%.*ls' 中插入重复的键行ls'。
但是这个呢..?
2627 - 违反 %ls 约束“%.*ls”。无法在对象 '%.*ls' 中插入重复的键。”
我刚刚花了一些时间准确地追踪这个问题。
如果我们更改数据库提供程序怎么办?大概 2601 不是绝对通用的...这很糟糕,IMO。如果你正在(正在)在表示层中处理这个问题,我认为还有更大的问题要问,
如果这必须是选择的机制,请将其深深埋藏在 DAL 中并让自定义。这样,对数据存储(或者理想情况下,这种机制)的更改的影响范围就更加有限,并且您可以一致地处理该情况,而不会在表示层中出现任何问题
。在打开的连接上对 ID 进行轻量级 SELECT 并完全避免异常。
I've just picked up a project where someone went down this route:
Note the following (from sys.messages in SQL Server):
2601 - Cannot insert duplicate key row in object '%.*ls' with unique index '%.*ls'.
But what about this..?
2627 - Violation of %ls constraint '%.*ls'. Cannot insert duplicate key in object '%.*ls'."
I just spent some time tracking down exactly this problem.
And what if we change DB provider? Presumably 2601 is not absolutely universal... This stinks, IMO. And if you are (were) dealing with this in your presentation layer, I think there are bigger questions to ask.
If this must be the mechanism of choice, bury it deep, deep down in the DAL and let a custom Exception percolate up. That way, changes to the data store (or, ideally, this mechanism) have a much more limited area of effect and you can handle the case consistently without any questions in the presentation layer.
I'm currently leaning towards doing a light-weight SELECT for an ID on an open connection and avoiding the exception altogether.
如此处所述,您可以使用异常过滤器。例子:
As documented here, you can use exception filters. Example:
仅过滤重复主键违规异常的工作代码
注意细节:-
ex.InnerException.InnerException
不是ex.InnerException
Working code for filter only duplicate primary key violation exception
Note fine detail :-
ex.InnerException.InnerException
notex.InnerException
对于初学者来说,您只能捕获 SqlException
You could only catch the SqlException for starters