我有一个 SQL 语句来检查某个值是否在我的数据库中。如果该值不在数据库中,我想用“快乐路径”进行响应。 我发现使用 DbDataReader (.NET),如果 SELECT 查询找不到值,它会抛出异常 - 所以我的“快乐路径”最终会出现在异常中,而不是出现在主 try block 中。
我总是可以说“NOT IN”,但我不想返回数据库中没有该值的所有行 - 因为这会返回数千个结果,而我想要的只是一个“不,它不在这里”类型响应。
public void wristbandScan(string barcode)
{
string query = "SELECT ticket FROM tickets WHERE
linked_barcode='" + barcode + "'";
ValidTicketEventArgs args = new ValidTicketEventArgs();
try
{
var queryResult = _dbRunner.queryThis(query);
args.Result = false;
args.Message = "WB already linked";
args.Barcode = barcode;
OnValidTicketEvent(args);
}
catch (Exception e)
{
this.updateWristband(barcode);
this.updateValid();
args.Result = true;
args.Message = "WB linked";
args.Barcode = barcode;
OnValidTicketEvent(args);
}
}
我觉得在错误语句中捕获快乐路径是错误的,但我不希望与使用 NOT IN 语句读取所有行相关的滞后。
是否有更好的方法来做到这一点,或者这种方法是否可以接受的最佳实践?
最佳答案
嗯,您不必获取所有记录到客户端;让我们为此提取一个方法。假设您使用 MS Sql
:
public bool hasScanCode(string barcode) {
if (string.IsNullOrWhiteSpace(barcode))
return false;
//DONE: paramterize queries
string query =
@"SELECT ticket
FROM tickets
WHERE linked_barcode = @prm_BarCode";
using (var conn = new SqlConnection(connection_string_here)) {
conn.Open();
using (var q = new SqlCommand(conn, query)) {
//TODO: q.Parameters.Add is a better choice
q.Parameters.AddWithValue("@prm_BarCode", barcode.Trim());
using (var reader = q.ExecuteReader()) {
// we read (fetch) at most 1 record
// if empty cursor - no record with given barcode
return reader.Read();
}
}
}
}
然后我们就可以使用它了:
public void wristbandScan(string barcode) {
bool result = hasScanCode(barcode);
ValidTicketEventArgs args = new ValidTicketEventArgs() {
Result = result,
Message = result ? "WB linked" : "WB already linked",
Barcode = barcode,
};
OnValidTicketEvent(args);
}
请记住 - 异常(exception)适用于特殊情况。异常非常慢(堆栈展开需要资源);它们不可读 - 事实上,catch 是臭名昭著的 goto;它们是危险 - 在您当前的代码中,您捕获
太多异常:例如AccessViolationException
如果在 dbRunner.queryThis
中的某处抛出,将被有效屏蔽。
关于c# - 在异常中捕获 "happy path"是一种不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56650279/