C#静态数据库类?

7
我有一个数据库类,包含以下方法:
  • public bool ExecuteUDIQuery(string query) // UDI = 更新 删除 插入
  • public bool ExecuteSelectQuery(string query)
  • public bool ExecuteSP(string sp, string[,] parms)
  • public int ExecuteSPReturnValue(string sp, string[,] parms)
这些方法的结果存储在私有数据集或数据表中。这些对象被定义为getter。
大约有10个类使用Database类。每个类都创建一个Database类的对象。现在我想把Database类变成静态的。这是一个好主意吗?如果是,为什么?如果不是,为什么不?
8个回答

5
如果我理解正确,数据库类有一些属性用于存储查询结果?如果是这样,那么您不能将它们设为静态的,因为这不是线程安全的。如果查询的结果存储在这些属性中,如果第二个查询紧随第一个查询执行,会发生什么?它将存储在同一静态变量中。对于Web应用程序也是如此:另一个用户浏览站点的结果会更改第一个用户的结果。

编辑:总之,当您将查询结果存储在静态变量中时,请勿使该类静态化,特别是在网站中使用该类时,因为属性值将在网站的所有访问者之间共享。如果同时有20个访问者进行查询,访问者1将看到访问者20的查询结果。


我正在建设一个网站。所以如果我理解你的意思正确的话,当有20个访问者并且他们都请求不同的页面(而我的数据库类是静态的)时,会出现问题,对吗? - Martijn
是的,你理解得很正确。如果这个类是静态的,那么属性将在整个应用程序中共享。因此,如果有20个访问者执行数据库查询,该属性将持有最后一个查询的结果,即访问者20的查询结果。 - Razzie

4
在您的具体示例中,我建议不要使类静态:您正在将状态保留在Database类中,通过使类静态,该状态将在使用您的Database的所有类之间共享。在您当前的设置中,每个Database实例都保留其自己的状态,因此Database调用彼此之间没有问题。
如果您重构Database类以在进行方法调用时返回数据集,则可以将其设为静态:在Database类中不会留下有状态的信息。
但由于这不是情况:不要使类静态。

2
我同意Inferis的观点。创建一个简化访问数据库类的Facade类可能是一个替代方案。 - Statement

2
除了其他关于线程安全的评论之外,还存在并行化问题。在您的情况下,即使结果的线程安全不是问题,您也无法同时打开多个与数据库的连接,也无法执行多个并行查询。
所以我同意其他人的观点,不要将其制作成静态类。
将类设为静态可能很方便,但创建新实例可能不会是一项昂贵的操作,因此在性能方面可能没有太大的收益。
编辑:
我在评论中看到你想在网站上使用你的类。在这种情况下,你真的不应该这样做。使用静态数据库类,您只能安全地服务于一个请求,而这不是您想要的。

1

这取决于你使用的数据库或ORM类型。但从我的经验来看,这似乎是一个好主意,但最终却让我失望了。以下是我在LINQ-to-SQL中的经历:

我有一个仓储类,其中有一个静态变量指向数据上下文。一开始它起作用了,但当我不得不创建更多仓储类时,我会遇到一些错误。结果发现,在LINQ-to-SQL中,数据上下文缓存了所有结果,而且没有办法刷新它们。因此,如果您在一个上下文中的表格中添加了一篇文章,那么在缓存该表格的其他上下文中就不会显示出来。解决方法是删除静态修饰符并让仓储在构造函数中创建上下文。由于当使用仓储类时会构造它们,因此也会产生新的数据上下文。

您可以说静态变量在内存中占用的空间较小,但数据上下文的占用空间本来就很小,而且最终会被垃圾回收。


1

与回答帖相反,我已经构建了一个具有静态数据库访问的Web框架,它运行良好且性能出色。

您可以在http://www.codeplex.com/Cubes上查看源代码。


0
如果你只是对数据库执行查询操作,那么确实可以将其设为静态的。只有在这个对象需要保持某种状态时才需要创建一个实例。

0
如果您有一个静态方法,需要在打开和关闭数据库时跟踪实例。
因此,您可能想要做的是创建一个名为“instance”或“current instance”的静态方法。在其中,您可以创建一个新的数据库类实例,并在静态方法中返回它。

保持“实例”开启并不是一个好主意。您应该尽快关闭与数据库的连接。 - Inferis
当然你应该关闭连接。但是如果你有一个用于访问命令的静态类,你可以在其中管理数据库连接。在完成后,有一个命令可以关闭读取器。 - Emil C

0

你的方法适用于静态使用。我认为,你现在将它们转换为静态方法没有问题。

但是以后可能需要管理事务。将事务管理留给一个类可以节省很多时间。这种情况最适合非静态类。


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