我一直感到期望定期抛出异常并将其用作流逻辑是一件坏事。异常感觉应该是“ 异常 ”。如果您期望并计划一个异常,那似乎表明您的代码应该被重构,至少在.NET中是这样。 但是。最近的情况让我停顿了一下。我之前在msdn上发布了此内容,但我想对此进行更多讨论,这是一个理想的地方!
因此,假设您有一个数据库表,该表具有一个针对其他几个表的外键(在最初引发辩论的情况下,有4个外键指向该表)。您要允许用户删除,但前提是没有外键引用。您不想级联删除。 我通常只是检查一下是否有引用,如果有,我会通知用户而不是删除。在LINQ中将相关表作为对象的成员是非常容易和轻松的,因此Section.Projects和Section.Categories等都可以用intellisense和所有类型很好地键入… 但是事实是LINQ必须可能会命中所有4个表以查看是否有任何结果行指向该记录,而命中数据库显然总是相对昂贵的操作。
这个项目的负责人要求我将其更改为仅捕获一个带有547(外键约束)代码的SqlException并以这种方式进行处理。
我… 抗拒 。
但是在这种情况下,吞下与异常相关的开销可能要比吞下4个表命中要高效得多……特别是因为我们必须在每种情况下都进行检查,但是在这种情况下我们可以避免异常当没有孩子时… 数据库真的应该是负责处理参照完整性的数据库,这就是它的工作,并且做得很好… 所以他们赢了,我改变了它。
在某种程度上,我还是觉得 不对 。
你们对期望和有意处理异常有何看法?看起来比事前检查更有效率吗?这会让下一个开发人员在看您的代码时更加困惑,还是减少了困惑?因为数据库可能知道开发人员可能不希望添加检查的新外键约束,这是否更安全?还是您对最佳实践到底是什么持观点看法?
哇,
首先,您能不能将问题简化一下,而阅读一个经过深思熟虑并能解释的问题真是太好了,需要消化的东西很多。
简短的回答是“是”,但这可以视情况而定。
File.Exists
在我看来:
我会 两者 都做。如果我可以快速失败并提供更好的用户体验,那就太好了。无论如何,任何预期的SQL(或任何其他)异常都应被捕获并适当地反馈。
我知道有一个共识,即除了特殊情况外,不应将异常用于其他 情况 ,但是请记住,我们在这里跨越了应用程序界限, 什么也没期待 。就像我说的,这就像File.Exists,没有意义,可以在访问之前将其删除。