我遇到的问题是try / catch块没有捕获异常。问题发生在 command.ExecuteReader(),但它永远不会被捕获。我在调试模式下运行,并且已经尝试了一些关于调试器设置的建议选项,但没有用。
我想提一下我使用SQLite作为我的提供程序,我可以看到它抛出SQLiteException,但问题仍然存在。是否存在未捕获异常的特定情况? (除了StackOverflowException,ThreadAbortedException等...)
public IEnumerable<dynamic> Query(string sql, params object[] parms)
{
try
{
return QueryCore(sql, parms);
}
catch (Exception ex)
{
throw new DbException(sql, parms, ex);
}
}
private IEnumerable<dynamic> QueryCore(string sql, params object[] parms)
{
using (var connection = CreateConnection())
{
using (var command = CreateCommand(sql, connection, parms))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return reader.ToExpando();
}
}
}
}
}
我还想补充一点,如果我对数据库产生了正确的查询,我会得到结果,但是当我中断查询时,会抛出异常,但不会被捕获。
答案 0 :(得分:5)
这是因为您使用yield关键字返回数据。 这使得数据实际数据方法仅在枚举其结果时才能运行。
您可能不希望这种情况发生,特别是因为如果结果被枚举两次(例如两个单独的foreach循环),数据将被读取两次。 您可以这样做以使枚举立即发生并捕获任何异常:
public IEnumerable<dynamic> Query(string sql, params object[] parms)
{
try
{
return QueryCore(sql, parms).ToArray();
}
catch (Exception ex)
{
throw new DbException(sql, parms, ex);
}
}
Yielding适用于获取项目需要一些时间的情况,并且您不希望在循环播放之前获取所有项目。所以另一个可能的解决方案,可能更好的代码的可读性(我认为不需要屈服)将是这样的:
public IEnumerable<dynamic> Query(string sql, params object[] parms)
{
try
{
return QueryCore(sql, parms);
}
catch (Exception ex)
{
throw new DbException(sql, parms, ex);
}
}
private IEnumerable<dynamic> QueryCore(string sql, params object[] parms)
{
using (var connection = CreateConnection())
{
using (var command = CreateCommand(sql, connection, parms))
{
using (var reader = command.ExecuteReader())
{
var results = new List<dynamic>();
while (reader.Read())
{
results.Add(reader.ToExpando());
}
return results;
}
}
}
}