在设计DataLayer或任何其他分层体系结构时如何处理异常

时间:2010-07-08 07:52:36

标签: design-patterns api exception exception-handling data-layers

我正在创建一个数据访问层,我想要处理业务层应该捕获的异常,并清楚地了解异常源。 我正在做这样的事情..

编辑

private void OpenConnection()
        {
                if (ConnectionState.Closed == _connection.State)
                    _connection.Open();
        }

在上面给出的代码中,我知道异常的原因。并且想把它扔在BL处理以显示消息。

但我在DL中只使用其他代码行来使用此功能。

protected DataTable GetDataTable(string Query)
 {
     DataTable dt =new DataTable();
     SqlCommand cmd = InitializeCommand(Query);

     SqlDataAdapter adp = new SqlDataAdapter(cmd);
     try
     {
         OpenConnection();
         adp.Fill(dt);
         CloseConnection(true);
         return dt;
     }
     catch (SqlException ex)
     { throw ex; }
     finally
     {
         adp.Dispose();
         cmd.Dispose();
     }
 }

现在,如果在OpenConnection()尝试打开连接时发生异常,则应用程序在OpenConnection本身的行throw ex崩溃,而我期望它返回异常。 我应该如何处理这个问题。 此外,如果发生异常,在第二个函数GetDataTable中扩展我的问题应该抛出什么样的异常与此时出现的相同细节以及如何发生。 我只知道这种方式,但我认为这是一种很好的方式。

throw new ApplicationException(ex.message,ex.innerexception)

修改

假设连接服务器丢失或我使用错误的连接字符串。现在我使用BL的GetDataTable函数。异常将在何处发生,我应该在哪里处理它? 我想知道DL中出现的问题。考虑到BL不知道DL的代码

2 个答案:

答案 0 :(得分:1)

你可以做几件事。

您可以拥有不同的try块,并根据您遇到问题的位置抛出新的异常:

 try
 {
     OpenConnection();
     adp.Fill(dt);
 }
 catch (SqlException ex)
 { throw new SqlException("Could not open/populate", ex); }
 finally
 {
     adp.Dispose();
     cmd.Dispose();
 }

 try
 {
     CloseConnection(true);
     return dt;
 }
 catch (SqlException ex)
 { throw new SqlException("Could not close connection", ex); }
 finally
 {
     adp.Dispose();
     cmd.Dispose();
 }

答案 1 :(得分:0)

我的建议是删除catch和rethrow,因为这会破坏异常的堆栈跟踪。你可以尝试没有捕获,因为你无论如何都要抛出异常。通过这种方式,您可以保留堆栈跟踪并仍然使用finally:

protected DataTable GetDataTable(string Query)
 {
     DataTable dt =new DataTable();
     SqlCommand cmd = InitializeCommand(Query);

     SqlDataAdapter adp = new SqlDataAdapter(cmd);
     try
     {
         OpenConnection();
         adp.Fill(dt);
         CloseConnection(true);
         return dt;
     }
     finally
     {
         adp.Dispose();
         cmd.Dispose();
     }
 }