为什么我要使用静态方法来访问数据库?

12

今天我遇到了这个问题,但是我找不到一些有意义的解释。在处理数据库交互时,是否存在某些非主观原因需要使用静态方法。

现在我正在一个通过存储过程完成所有操作的项目上工作,例如我有一些常规方法:

public void Delete(int clientID)
    {
      //calling store procedure
    }
或者
public void Save(int clientID)
    {
      //calling store procedure
    }

但我也有:

public static Client GetByID(int id)
    {
        //calling stored procedure
    }
public static int AddNew(string firstName, string lastName...)
    {
      //calling store procedure
    }

由于我已经使用.NET约9个月,并且只使用Entity Framework和Repository Pattern,因此我无法回忆起任何地方或任何代码中使用了静态方法。既不是用于标准CRUD操作,也不是用于与数据库相关的更特定的任务。

那么这是否与访问数据库的特定方式有关,是否是可以提高性能的某种实践,还是只是开发人员的方法,当在我的与数据库相关的方法中何时使用静态方法时,我不应过多考虑?


@Anon 是的,这是一个ASP.NET Web Forms应用程序。 - Leron
更多阅读:https://dev59.com/53VC5IYBdhLWcg3wnCWA https://dev59.com/0lTTa4cB1Zd3GeqPqThx - Andrew Morton
4个回答

13

对于数据访问层,我会避免使用静态方法,因为一个简单的原因...耦合性。

静态方法无法实现接口,而实例方法可以。通过使用静态方法,人们实际上是坚持不按照接口编码,而是按照实现编码。因此,使用这个数据访问层的所有内容 必须 始终依赖于这个 特定的 数据访问层。

没有备选方案,没有测试存根,完全没有依赖反转。业务逻辑有一个依赖于基础设施问题(数据访问层)的箭头,而实际情况应该相反。


此外,它似乎至少带来了更大的 风险,可能存在资源释放方面的问题。在这种情况下可能并非如此,但是很容易变成这样。如果开发者想要将公共代码提取到类级别的静态方法和属性中,例如 ConnectionDBContext 对象,那么将会产生一些非常有趣和 非常 难以调试的运行时错误。

另一方面,如果 repository 是实例,则可以简单地实现 IDisposable 并确保正确处理任何类级别的对象。


继续(我想我对设计有更多异议),从面向对象的角度来看,这很反直觉。也许这只是个人偏好,但是这将本来应该是“存储库对象”变成了“数据库帮助程序方法的转储场所”。

在这样的系统中,我会期望随着时间的推移,数量不断增加的非常规方法,因为开发人员为了满足需求而快速制定解决方案,而不考虑整体架构。你可能最终得到一个膨胀并且难以跟进的代码库,而不是一系列一致且良好管理的对象。


哈哈,就好像你描述的这个项目一样。我很惊讶一个小细节可以如此轻松甚至不易察觉地导致其他问题,最终像你所写的那样变成了一个“臃肿且难以跟踪的代码库”。我会多读几遍你的答案,真的很好。谢谢。 - Leron
非常棒的答案,完美地描述了我在接手现有Web应用程序项目时尝试添加单元测试时遇到的困难。我一定会在今后利用这个答案! - wjhguitarman

3

静态方法在没有状态或共享状态时使用。如果您的代码仅调用存储过程,则除了共享的数据库连接字符串之外,可能没有任何状态。这将是静态方法的有效用法。


当然,把这些方法设置为静态的没有问题,但我想知道是否有比使其静态更重要的原因。它可以正常工作,但根据我的经验,这种将方法设置为静态的做法并不常见。但是我可能也错了,所以我想问一下... - Leron
在编程中,如果调用存储过程可能会导致唯一共享数据是连接字符串,这一点需要特别注意。我们在软件中使用这种方法来维护数据的一致性和安全性。 - Michael J. Gray

1

我认为你最后的陈述是正确的;那只是之前开发者的方法。

不过,我要说的是,将这些方法设置为静态的会让你在创建可测试产品时生活成为一场噩梦;如果你有能力将它们改为基于实例,并创建一组单元测试可以通过模拟而不需要数据库来测试应用程序,这将使你的生活更轻松。


1
我们无法从发布的示例中确定,但如果这些方法仅仅是调用存储过程,那么可能没有什么可以测试或模拟的东西。 - Moby Disk

0
在我们公司这里,我们很少使用它们,尽管它们可以在实用类或仅调用函数的类似事物中发挥作用。根据非静态类的实例数量,它们也可能会影响性能,但这需要显著的实例差异。来源-MSDN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接