【问题标题】:How Exceptions are handled while designing DataLayer or any other layered architecture在设计 DataLayer 或任何其他分层架构时如何处理异常
【发布时间】:2010-07-08 07:52:36
【问题描述】:

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

编辑

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的代码

【问题讨论】:

  • 在您的第一个代码示例中,如果您要做的只是重新抛出异常,为什么还要使用try{}catch{}?只需删除所有这些。
  • @Oded:我不知道该怎么做。如果我从第一个块中删除 try catch,它将在我使用它的函数中得到处理。
  • 这与现在发生的情况有何不同?您正在重新抛出异常,它会在使用它的函数中得到处理...
  • @Oded:请检查编辑并提供一些有用的建议。

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


【解决方案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();
 }

【讨论】:

  • 由于 SqlException 不会像这样显式抛出。 throw new SqlException(""), 应该改用什么。是否建议在同一个函数中使用多个 try catch。
  • @Shantanu Gupta - 这只是说明您可以做什么。您可以创建自己的更具描述性的异常类(OpenConnectionExceptionCloseConnectionException)并抛出它们。
  • 假设我创建了一个 OpenConnectionException 并将其抛出到 OpenConnection 函数中,而不是可以在 BL 中处理它,但有一些一般异常,比如 DataLayerException,它将为我提供实际发生异常的详细信息。
  • @Shantanu Gupta - 是的。当您抛出异常时,它将具有这些详细信息。您应该创建自己的 DataLayerException 并让其他人继承它。
【解决方案2】:

我的建议是删除捕获并重新抛出,因为这会破坏异常的堆栈跟踪。您可以尝试不捕获,因为无论如何您都会抛出异常。通过这种方式,您可以保留堆栈跟踪并仍然使用 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();
     }
 }

【讨论】:

  • 创建一个自定义异常类,比如 DataLayerExcetpion 并从那里抛出 ApplicationException 以及从这里发送的消息和 innerException 不是更好吗?
  • 是的,你可以,但它对以后的调试有帮助吗?我更喜欢一种简单的方法,以便您知道异常发生的位置以及异常本身的消息。真的不需要额外的信息。但我更喜欢保持简单。
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
  • 2014-12-18
  • 2014-11-03
  • 2018-01-04
相关资源
最近更新 更多