C# 抓到“我”是一种坏习惯吗;“快乐之路”;有例外吗?
我有一个SQL语句,它检查一个值是否在我的数据库中。如果值不在数据库中,我想用“快乐路径”来响应。 我发现使用DbDataReader(.NET)时,如果SELECT查询找不到值,它会抛出一个异常-因此我的“快乐路径”最终出现在异常中,而不是主try块中 我总是可以说“notin”,但我不想返回数据库中所有没有该值的行,因为这将返回数千个结果,而我只需要一个“no it is NOT here”类型的响应C# 抓到“我”是一种坏习惯吗;“快乐之路”;有例外吗?,c#,sql,error-handling,try-catch,C#,Sql,Error Handling,Try Catch,我有一个SQL语句,它检查一个值是否在我的数据库中。如果值不在数据库中,我想用“快乐路径”来响应。 我发现使用DbDataReader(.NET)时,如果SELECT查询找不到值,它会抛出一个异常-因此我的“快乐路径”最终出现在异常中,而不是主try块中 我总是可以说“notin”,但我不想返回数据库中所有没有该值的行,因为这将返回数千个结果,而我只需要一个“no it is NOT here”类型的响应 public void wristbandScan(string barcode)
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语句的所有行相关联的延迟
是否有更好的方法来执行此操作,或者此方法是可接受的最佳做法?创建并调用一个StoredProcess,它可以处理空情况,不返回任何行而不是异常 然后处理
try/catch
之外的无行场景。好吧,您不必将所有记录提取到客户端;让我们为此提取一个方法。假设您使用的是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);
}
请记住,例外情况适用于特殊情况。异常非常缓慢(堆栈展开需要资源);它们不可读-
catch
,事实上,它是一个臭名昭著的goto
;它们是危险的-在您当前的代码中,您捕获了太多的异常:例如,AccessViolationException
,如果它被抛出到dbRunner中的某个地方。查询此
将被有效屏蔽。是的,非常糟糕的做法。例外是非常昂贵的,应该是:例外,不是你期望发生的事情,更不用说“快乐”的结果了!我就是这么想的。那么,如何让SELECT语句在找不到值时不返回异常呢?也许限制是我对SQL的了解?通常,如果一个SELECT查询找不到值,它会抛出一个异常?在什么情况下是真的??通常,查询返回一个空结果集。什么是\u dbRunner.queryThis
?最好从一个类似ORM(对象到关系管理器)的实体框架开始(还有其他选项可用),此时您可以将表视为对象的集合,而不必担心底层的SQL代码。它还可以消除当前代码可能遭受的SQL注入攻击。我不知道为什么SELECT
会抛出异常如果找不到结果,它应该返回一个空集。但是,如果您只关心条形码的存在,您可以将查询从链接的票证更改为COUNT(1)\u barcode=
。如果找不到匹配项,这将返回0,否则将返回大于0的值谢谢这个解决方案,我重新设计了我的实现,效果很好。