小编典典

将异常捕获为预期的程序执行流控制?

sql

我一直感到期望定期抛出异常并将其用作流逻辑是一件坏事。异常感觉应该是“ 异常
”。如果您期望并计划一个异常,那似乎表明您的代码应该被重构,至少在.NET中是这样。
但是。最近的情况让我停顿了一下。我之前在msdn上发布了此内容,但我想对此进行更多讨论,这是一个理想的地方!

因此,假设您有一个数据库表,该表具有一个针对其他几个表的外键(在最初引发辩论的情况下,有4个外键指向该表)。您要允许用户删除,但前提是没有外键引用。您不想级联删除。
我通常只是检查一下是否有引用,如果有,我会通知用户而不是删除。在LINQ中将相关表作为对象的成员是非常容易和轻松的,因此Section.Projects和Section.Categories等都可以用intellisense和所有类型很好地键入…
但是事实是LINQ必须可能会命中所有4个表以查看是否有任何结果行指向该记录,而命中数据库显然总是相对昂贵的操作。

这个项目的负责人要求我将其更改为仅捕获一个带有547(外键约束)代码的SqlException并以这种方式进行处理。

我…
抗拒

但是在这种情况下,吞下与异常相关的开销可能要比吞下4个表命中要高效得多……特别是因为我们必须在每种情况下都进行检查,但是在这种情况下我们可以避免异常当没有孩子时…
数据库真的应该是负责处理参照完整性的数据库,这就是它的工作,并且做得很好…
所以他们赢了,我改变了它。

在某种程度上,我还是觉得 不对

你们对期望和有意处理异常有何看法?看起来比事前检查更有效率吗?这会让下一个开发人员在看您的代码时更加困惑,还是减少了困惑?因为数据库可能知道开发人员可能不希望添加检查的新外键约束,这是否更安全?还是您对最佳实践到底是什么持观点看法?


阅读 178

收藏
2021-04-07

共1个答案

小编典典

哇,

首先,您能不能将问题简化一下,而阅读一个经过深思熟虑并能解释的问题真是太好了,需要消化的东西很多。

简短的回答是“是”,但这可以视情况而定。

  • 我们有一些应用程序,其中许多业务逻辑与SQL查询相关联(不是我的设计Gov!)。如果这是它的结构方式,那么管理层就很难说服其他方面了,因为它“已经有效”。
  • 在这种情况下,真的有意义吗?由于仍然是一次穿越电线并返回的旅程。服务器在意识到它无法继续之前是否做了很多工作(即,如果要执行一系列的事务来执行您的操作,那它是否会浪费掉一半时间而浪费时间?)。
  • 首先在UI中进行检查是否有意义?它对您的应用程序有帮助吗?是否提供更好的用户体验?(即,我已经看到了您在向导中逐步执行几个步骤的情况,当它具有在步骤1之后需要移交的所有信息时,它将启动,然后移交)。
  • 并发问题吗?是否有可能在提交之前删除/编辑记录或进行其他任何操作(如经典的File.Existsboo-boo一样)。

在我看来:

我会 两者 都做。如果我可以快速失败并提供更好的用户体验,那就太好了。无论如何,任何预期的SQL(或任何其他)异常都应被捕获并适当地反馈。

我知道有一个共识,即除了特殊情况外,不应将异常用于其他 情况 ,但是请记住,我们在这里跨越了应用程序界限, 什么也没期待
。就像我说的,这就像File.Exists,没有意义,可以在访问之前将其删除。

2021-04-07