当ADO.NET查询无法检索所请求的数据时,应该引发什么异常?

时间:2020-03-06 14:36:19  来源:igfitidea点击:

为了向我们的应用程序中添加一些参数验证和正确的用法语义,我们尝试向.NET应用程序中添加正确的异常处理。

我的问题是:如果特定查询没有返回数据或者找不到数据,则在ADO.NET中引发异常时,应使用哪种类型的异常?

伪代码:
(阅读,不要仔细检查代码的语义,我知道它不会编译)

public DataSet GetData(int identifier)
{
    dataAdapter.Command.Text = "Select * from table1 Where ident = " + identifier.toString();
    DataSet ds = dataAdapter.Fill(ds);
    if (ds.table1.Rows.Count == 0)
        throw new Exception("Data not found");

    return ds;
}

解决方案

就ADO.net而言,返回零行的查询不是错误。如果应用程序希望将此类查询视为错误,则应通过从Exception继承来创建自己的异常类。

public class myException : Exception
{
   public myException(string s) : base() 
   {
      this.MyReasonMessage = s;
   }
}

public void GetData(int identifier)
{
    dataAdapter.Command.Text = "Select * from table1 Where ident = " + identifier.toString();
    DataSet ds = dataAdapter.Fill(ds);
    if (ds.table1.Rows.Count == 0)
        throw new myException("Data not found");
}

我们确实应该定义自己的异常:DataNotFoundException。

我们不应该使用基本类Exception,因为当我们在调用代码中捕获它时,我们将编写类似

try
{
     int i;
     GetData(i);

}
catch(Exception e) //will catch many many exceptions
{
    //Handle gracefully the "Data not Found" case;
    //Whatever else happens will get caught and ignored
}

在仅捕获DataNotFoundEXception的情况下,只会得到我们真正想要处理的情况。

try
{
     int i;
     GetData(i);

}
catch(DataNotFoundException e) 
{
    //Handle gracefully the "Data not Found" case;
} //Any other exception will bubble up

当SQL引擎出现问题时,有一个恰当地命名为SqlException的类,但最好不要在业务逻辑中重载它

MSDN指南指出:

  • 考虑抛出驻留在系统名称空间中的现有异常,而不是创建自定义异常类型。
  • 如果我们所遇到的错误情况可以通过编程方式与其他任何现有异常不同的方式进行处理,则请创建并引发自定义异常。否则,抛出现有异常之一。
  • 不要仅仅为了拥有团队的例外就创建和抛出新的例外。

没有硬性规定:但是,如果我们有不同方式处理此异常的方案,请考虑创建自定义异常类型,例如Johan Buret建议的DataNotFoundException。

否则,我们可能会考虑抛出现有的异常类型之一,例如System.Data.DataException甚至可能抛出System.Collections.Generic.KeyNotFoundException。