我有一个方法可以返回是否可以打开连接。
但是,如果发生故障,我需要通知用户他们是否提供了错误的登录凭据,或者数据库是否存在问题。
当前代码:
try
{
Database db = new SqlDatabase(connectionString);
using(var connection = db.CreateConnection())
{
connection.Open();
return true;
}
}
catch (Exception ex)
{
return false;
}
无论是凭据还是数据库的问题,异常始终是SqlException
。
但是,我注意到以下差异:
凭据错误:
Login failed for user 'whatever'
14
18456
1
数据库错误:
A network something or other
20
-1
0
...是的,有差异,但我不确定我可以依赖这些数字(检查信息的字符串值让我觉得我需要洗澡)。
根据MSDN,Number
属性可以是Win32错误代码或服务器错误代码,Class
表示严重性,State
可以给出不同错误代码的不同含义。
有更好的方法来确定连接失败吗?
答案 0 :(得分:4)
Sql Server错误代码为documented,您绝对可以依赖它们!
答案 1 :(得分:3)
由于Class
属性映射到SQL Server报告的错误的Severity,您可以使用它来确定需要执行的操作。
从SQL Server严重性表中我们了解到:
您的方法可以返回状态代码,具体取决于用户是否可以修复严重性。哪个类别的代码符合您的特定要求,但您可以想象这样的代码:
public enum Status
{
Success = 0,
None,
RetryUser,
RetryInfra,
Network,
Boom,
MAX
}
public Status ConnectionStatus()
{
Status status = Status.None;
try
{
Database db = new SqlDatabase(connectionString);
using (var connection = db.CreateConnection())
{
connection.Open();
status = Status.Success;
}
}
catch (SqlException ex)
{
switch (ex.Class)
{
case 11:
case 12:
case 13:
case 14:
status = Status.RetryUser;
break;
case 20:
status = Status.RetryInfra;
break;
default:
status = Status.Boom;
break;
}
}
return status;
}
从MSDN的Understanding Database Engine Errors我们了解到State
可能不是确定下一步的正确选择:
可以在数据库引擎的代码中的多个点处引发一些错误消息。例如,可以针对几种不同的条件引发1105错误。引发错误的每个特定条件都会分配一个唯一的状态代码。