为什么不从DB读取C#属性getter?

这个问题的一些答案和评论: 最简单的C#代码来调查一个属性? ,暗示从属性的getter中的数据库中检索数据通常是一个坏主意。
为什么这么糟糕?

(如果您有自己的信息来源,请提及。)


我通常会在第一次“获取”之后将信息存储在变量中以供重用,如果这会影响您的答案。

因为从数据库中检索数据可能会导致任意数量的exception,并且属性获取者通常不应该抛出exception。

属性getter的预期行为只是返回一个值; 如果它实际上做的远不止于此,它应该是一种方法。

我知道微软的某些文档提供了不更详细地抛出exception的原因,但我无法找到它。 如果我这样做,我将用它的链接替换它。 这可能是它,但我不确定: http : //msdn.microsoft.com/en-us/library/bzwdh01d%28VS.71%29.aspx#cpconpropertyusageguidelinesanchor1

这很糟糕,因为(除其他外)它违反了最小惊讶原则 。

程序员通常希望属性做简单的获取/设置。 在属性中封装数据访问可能会导致exception,导致副作用以及更改数据库中数据的状态,这不是通常所期望的。

我并不是说没有复杂属性的情况 – 有时,它可能是一个很好的解决方案。 但是,这不是预期的做事方式。

简短版本:使财产获取者直接访问数据库将违反“ 关注分离”原则。

更多细节:一般来说,属性旨在表示与对象关联的数据,例如Person对象的FirstName属性。 属性值可以在内部或外部设置,但是在对象上修改和检索此数据的行为应该与检索或将该数据提交到永久存储的行为分开。

每当你访问getter时,你都会再次调用你的数据库。

根据定义,getter应该只是封装数据,而不是function。

此外,如果您有多个需要往返数据库的getter,您可能会重新定义function并多次访问数据库。 为什么不在集中的地方处理它而不是在多个属性中分割出来?

方法用于类级数据修改和function,属性仅用于单个数据修改和检索。

除了可能的exception之外,查询数据库是一种懒惰的操作。 在这两个方面,使用属性getter作为数据库访问器违反了对客户端代码最不惊讶的原则 。 如果我看到一个带有属性的库类,我不希望它做很多工作,而是访问一个容易检索的值。

这里最不惊人的选择是提供一种老式的,简单的Getfunction。

如果您确实只是从数据库中检索值而不是将其值写回(例如只读属性),则没有任何内在错误。 特别是如果没有父母的财产不能存在。 但是在实现中,它可能导致可维护性问题。 您正在通过访问该信息来检索存储信息的过程。 如果您继续对其他属性使用此模式,并且存储系统的各个方面发生更改,则更改可能会在整个代码库中激增。 例如,表名或列数据类型更改。 这就是为什么在属性getter中进行数据库调用很糟糕。

请注意:如果数据库在您尝试检索值时抛出exception,那么您的代码(或调用客户端代码)中显然存在错误,无论您将数据访问代码放在何处,exception仍会出现exception。 很多时候,数据由类中可能抛出exception的某种集合支持,并且以这种方式存储属性值是标准做法(请参阅EventHandlerList )。

属性是专门设计的,因为程序员在获取和设置值时需要执行额外的逻辑,例如validation。

说完所有这些,重新审视你的代码,并问自己“以后改变会有多容易?” 从那里你应该开始一个更易于维护的解决方案。