【问题标题】:Should we throw an exception if the resource we are trying to update results in no rows affected?如果我们尝试更新的资源没有影响任何行,我们是否应该抛出异常?
【发布时间】:2021-05-04 09:31:01
【问题描述】:
我正在尝试实现存储库模式。我有一个疑问,假设我们正在尝试对不存在的记录执行更新。在这种情况下我们应该抛出异常吗?如果是,我们应该抛出ArgumentException 还是InvalidOperationException?
在ArgumentException 的情况下,输入无效。但输入可以是有效的,但记录仍然不存在。那么我们是否应该在尝试对不存在的资源执行操作时抛出InvalidOperationException?
【问题讨论】:
标签:
c#
oop
design-patterns
software-design
【解决方案1】:
为了回答这样的问题,我首先尝试想象一下可能导致这种情况发生的原因。
如果您的更新不影响任何行,则可能是由以下情况之一引起的:
- 在并发系统中,该记录可能在发出 update 时已经存在,但另一个并发操作在它到达数据库之前将其删除。在乐观的锁定方案中,所涉及的时间范围很容易是几分钟,因此这并不像听起来那么不可能。
- 调用update过程的程序员出错了。
在这两种情况下,我认为调用者都想知道操作失败。客户端调用较低级别的代码有一些intent。在这里,目的是更新记录。如果更新没有发生,那么较低级别的代码无法执行意图。这可能会发生,但应该通知给调用者。虽然在技术上可以忽略此类情况,但许多错误可能隐藏在此类行为背后。
简而言之:抛出异常。
具体来说,抛出一个InvalidOperationException。作为the documentation states:
InvalidOperationException 用于由于无效参数以外的原因导致方法调用失败的情况。通常,当对象的状态不能支持方法调用时,会抛出它。
确实,一个错误可能使调用代码调用具有不存在记录的方法,在这种情况下,您可以争辩说问题是参数,而不是系统的状态。
但是,应该修复错误。即使存在这样的错误,一旦你解决了它,它就消失了,你将不再有无效的论点。因此,虽然并发是您必须处理的现实,但只要不存在错误,就不应观察到无效参数。