30岁,我在做什么?

.NET SQL数据库 Office开发 办公自动化

导航

NET 数据访问架构指南

Posted on 2007-06-20 00:41  .net 世界  阅读(189)  评论(0)    收藏  举报

缓存并处理.NET异常


要处理数据访问例外状态,将数据访问代码放在try块中,并在catch块中利用合适的过滤器捕获生成的任何例外。例如,当利用SQL Server .NET数据供应器编写数据访问代码时,应当捕获SqlException类型的异常,如下面的代码所示:

try
{
// Data access code
}
catch (SqlException sqlex) // more specific
{
}
catch (Exception ex) // less specific
{
}

如果为不止一个catch声明提供了不同的过滤标准,记住,按最特殊类型到最不特殊类型的顺序排列它们。通过这种方式,catch块中最特殊类型将将为任何给定的类型所执行。

SqlException 类所暴露的属性包含了例外状态的细节。其中包括:

  • Message属性,它包含了用于描述错误的文本。
  • Number属性,它包含唯一标识错误类型的错误号。
  • State属性。它包含了关于错误启用状态的附加信息。它经常用于指示特殊错误状态的某个特定事件。例如,如果单一存储过程从不止一行中生成同样的错误,那么本属性将用于标识某个具体的事件。
  • Errors集合。它包含了SQL Server生成的错误的详细信息。此集合部是包含至少一个SqlError类型的对象。

下面的代码片段演示了如何利用SQL Server .NET数据供应器处理SQL Server 错误状态:

using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
// Method exposed by a Data Access Layer (DAL) Component
public string GetProductName( int ProductID )
{
SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=northwind");
// Enclose all data access code within a try block
try
{
conn.Open();
SqlCommand cmd = new SqlCommand("LookupProductName", conn );
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ProductID", ProductID );
SqlParameter paramPN =
cmd.Parameters.Add("@ProductName", SqlDbType.VarChar, 40 );
paramPN.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
// The finally code is executed before the method returns
return paramPN.Value.ToString();
}
catch (SqlException sqlex)
{
// Handle data access exception condition
// Log specific exception details
LogException(sqlex);
// Wrap the current exception in a more relevant
// outer exception and re-throw the new exception
throw new DALException(
"Unknown ProductID: " + ProductID.ToString(), sqlex );
}
catch (Exception ex)
{
// Handle generic exception condition . . .
throw ex;
}
finally
{
conn.Close(); // Ensures connection is closed
}
}
// Helper routine that logs SqlException details to the
// Application event log
private void LogException( SqlException sqlex )
{
EventLog el = new EventLog();
el.Source = "CustomAppLog";
string strMessage;
strMessage = "Exception Number : " + sqlex.Number +
"(" + sqlex.Message + ") has occurred";
el.WriteEntry( strMessage );
foreach (SqlError sqle in sqlex.Errors)
{
strMessage = "Message: " + sqle.Message +
" Number: " + sqle.Number +
" Procedure: " + sqle.Procedure +
" Server: " + sqle.Server +
" Source: " + sqle.Source +
" State: " + sqle.State +
" Severity: " + sqle.Class +
" LineNumber: " + sqle.LineNumber;
el.WriteEntry( strMessage );
}
}

在SqlException catch块中,代码最初利用LogException帮助函数记录错误状态,此函数利用foreach声明枚举了Errors集合中特定于供应器的细节,并将错误细节记录到错误日志中。 Catch块中的代码然后将特定于SQL Server的例外封装在DALException类型的对象中,这样做对调用者的GetProductName方法更具有意义。例外处理程序使用关键字throw将例外传回调用者。