如果你从事过 PPC 上的 .NET Compact Framework 1.0 和 SQL Server CE 2.0 的开发,应该已经跟 SqlCeException 交过手了。本文将向初学者介绍如何正确地捕获和有效地处理 SqlCeException。
一、捕获SqlCeException
在 .NET Compact Framework 1.0 中,SqlCeException 是一个需要特殊处理的异常类,如果你不对它进行单独的捕获,获取到的异常信息将是"SqlCeException"或者空字符串,而不是你想要获取到的真实异常信息。接下来我给大家分析几段代码:
[代码1]
{
// 创建一个数据库连接,连接字符串中的数据库是不存在的
SqlCeConnectionconn = new SqlCeConnection( " DataSource=nonExistSource.sdf; " );
// 打开数据库连接,将抛出一个SqlCeException
conn.Open();
}
catch (Exceptionex)
{
// 获取到的异常信息是空白字符串
MessageBox.Show(ex.Message);
}
[代码1]中的异常处理代码捕获到的是一个 SqlCeException 的异常实例,在 catch 块中没有对该实例进行类型转换,直接就获取它的 Message 值,得到的错误信息将是空白字符串,并非原始的异常信息。再看看[代码2]:
[代码2]
{
// 创建一个数据库连接,连接字符串中的数据库是不存在的
SqlCeConnectionconn = new SqlCeConnection( " DataSource=nonExistSource.sdf; " );
// 打开数据库连接,将抛出一个SqlCeException
conn.Open();
}
catch (SqlCeExceptionssex)
{
// 获取到的异常信息如下:
// "Thedatabasefilecannotbefound.Checkthepathtothedatabase.[,,,Filename,,]"
MessageBox.Show(ssex.Message);
}
catch (Exceptionex)
{
// 获取其他异常信息
MessageBox.Show(ex.Message);
}
在[代码2]中,我们对 SqlCeException 单独捕获,最后获取到了原始的错误信息"The database file cannot be found. Check the path to the database. [,,,File name,,]"。
二、处理SqlCeException
如果你有一个对异常进行统一处理的类和方法,如:ExceptionManager.Publish(Exception exception)。根据我上面的分析,你不得不在 Pulibsh 方法中对 SqlCeException 进行类型转化。如[代码3] 所示:
[代码3]
sb.Append( " Message: " );
if (exception is SqlCeException)
{
sb.Append(((SqlCeException)exception).Message);
}
else
{
sb.Append(exception.Message);
}
从 SqlCeException.Message 属性获取到的错误信息往往是不够详细的,因为这些信息是在 SQL Server CE 2.0 中预先定义好的。我们希望获取到更加详细的错误信息,能够指导我们迅速找到出错代码的具体位置。比如在[代码2]中,我们想要知道找不到的数据库文件名称是什么。其实除了 Message 属性外,从 SqlCeException 中还可以获取到更多的错误信息,请看[代码4]:
[代码4]
/// 产生一个详细错误消息的SqlCeException异常处理程序。
/// </summary>
/// <paramname="exception"> SqlCeException异常对象。 </param>
public static void ShowErrors(SqlCeExceptionexception)
{
// 获取包含一个或多个SqlCeError对象的集合,这些对象包含有关
// SQLServerCE.NETFramework精简版数据提供程序产生的异常的详细信息。
SqlCeErrorCollectionerrs = exception.Errors;
// 获取导致当前异常的Exception实例。
Exceptioninner = exception.InnerException;
if ( null != inner)
{
// 显示内部异常信息。
MessageBox.Show( " InnerException: " + inner.ToString());
}
StringBuildersb = new StringBuilder();
// 用消息框显示每个错误的详细信息
foreach (SqlCeErrorerr in errs)
{
// 标识错误类型的HRESULT值,这些错误不是SQLServerCE固有的。
sb.Append( " ErrorCode: " ).Append(err.HResult.ToString( " X " ));
// 对错误进行描述的文本。
sb.Append( " \nMessage: " ).Append(err.Message);
// 获取SqlCeError的本机错误号。
sb.Append( " \nMinorErr.: " ).Append(err.NativeError);
// 生成错误的提供程序的名称。
sb.Append( " \nSource: " ).Append(err.Source);
// 遍历前三个错误参数。SQLServerCE使用错误参数来提供有关错误的其他详细信息。
foreach ( int numPara in err.NumericErrorParameters)
{
// 虽然错误可能存在参数,但并非发生的所有错误都返回参数。
// 如果发生某个错误时没有返回任何参数,则该数组的值为0。
if ( numPara!=0)
{
sb.Append( " \nNum.Par.: " ).Append(numPara);
}
}
// 遍历最后三个错误参数。SQLServerCE使用错误参数来提供有关错误的其他详细信息。
foreach ( string errPara in err.ErrorParameters)
{
// 虽然错误可能存在参数,但并非发生的所有错误都返回参数。
// 如果发生某个错误时没有返回任何参数,则该数组的值将为空字符串。
if (errPara != String.Empty)
{
sb.Append( " \nErr.Par.: " ).Append(errPara);
}
}
MessageBox.Show(sb.ToString());
sb.Remove( 0 ,sb.Length);
}
}
我们可以使用[代码4]中的 ShowErrors 方法来处理[代码2]中的 SqlCeException 异常。
[代码5]
{
// 创建一个数据库连接,连接字符串中的数据库是不存在的
SqlCeConnectionconn = new SqlCeConnection( " DataSource=nonExistSource.sdf; " );
// 打开数据库连接,将抛出一个SqlCeException
conn.Open();
}
catch (SqlCeExceptionssex)
{
// 获取详尽的异常信息
ShowErrors(ssex);
}
catch (Exceptionex)
{
// 获取其他异常信息
MessageBox.Show(ex.Message);
}
异常信息的内容如下图所示:
三、总结
本文介绍的内容是我这段时间在项目开发中总结的经验,希望对刚刚接触 SQL Server CE 开发的人在处理 SqlCeException 上有帮助。
示例代码
[参考]
SQL Server CE 2.0 Books Online: Error Handling in C#
原文地址:http://www.cnblogs.com/upto/archive/2005/11/24/HandlingSqlCeException.html