6

我有一个包含以下方法的数据库类:

  • public bool ExecuteUDIQuery(string query) // UDI = 更新删除插入
  • public bool ExecuteSelectQuery(字符串查询)
  • public bool ExecuteSP(string sp, string[,] parms)
  • public int ExecuteSPReturnValue(string sp, string[,] parms)

方法的结果存储在私有数据集或数据表中。这些对象被定义为 getter。

大约有 10 个类使用 Database 类。每个类都创建类数据库的一个对象。现在我正在考虑使数据库类静态。这是一个好主意吗?如果是这样,为什么?不,为什么不呢?

4

8 回答 8

5

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

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

于 2009-03-12T08:28:02.867 回答
4

在您的具体示例中,我建议不要将类设为静态:您将状态保持在 Database 类中,并且通过使类成为静态,该状态将在使用您的 Database 的所有类之间共享。在您当前的设置中,每个数据库实例都保持自己的状态,因此数据库调用相互干扰没有问题。

如果您在进行方法调用时重构 Database 类以返回数据集,那么将其设为静态就可以了:Database 类中不会留下任何有状态的信息。

但既然情况并非如此:不,不要使类成为静态的。

于 2009-03-12T08:28:24.427 回答
2

除了其他关于线程安全的评论之外,还有并行化问题。在您的情况下,您将无法同时打开与数据库的多个连接,并且您将无法执行多个并行查询,即使结果的线程安全不是问题。

所以我同意其他人的观点,不要用它制作静态类。

将类设为静态可能很方便,但创建它的新实例可能不会是一项昂贵的操作,因此在性能方面也可能没有太多收获。

编辑:
我在评论中看到您想在网站上使用您的课程。在那种情况下,你真的不应该这样做。使用静态数据库类,您在任何时候都只能安全地处理一个请求,而这不是您想要的。

于 2009-03-12T08:36:04.767 回答
1

这取决于您使用的是哪种数据库或 ORM。但根据我的经验,这似乎是一个好主意,但最终让我感到厌烦。以下是它在 LINQ-to-SQL 中对我的作用:

我有一个存储库类,它有一个数据上下文的静态变量。起初它是有效的,但是当我不得不制作更多的存储库类时,我最终发现了错误,因为我一直在破解。事实证明,LINQ-to-SQL 中的数据上下文缓存了所有结果,并且无法刷新它们。因此,如果您在一个上下文中的表中添加了一篇文章,则它不会显示在缓存该表的其他表中。解决方案是删除静态修饰符并让存储库在构造函数中创建上下文。由于存储库类是在使用时构建的,因此也将构建一个全新的数据上下文。

您可能会争辩说静态变量在内存中留下的足迹更少,但数据上下文的足迹一开始就非常小,最终将被垃圾收集。

于 2009-03-12T08:29:07.357 回答
1

与答案帖子相反。我已经构建了一个具有静态数据库访问权限的网络框架,它工作得很好并且性能很好。

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

于 2009-03-12T20:34:51.487 回答
0

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

于 2009-03-12T08:22:09.417 回答
0

如果您有静态方法,则需要在打开和关闭数据库时跟踪实例。

所以你可能想要做的是有一个名为实例或当前实例的静态方法。并在您创建一个新的数据库类实例,以静态方法返回它。

于 2009-03-12T08:22:52.317 回答
0

您的方法适合静态使用。我认为,您现在可以轻松地将它们转换为静态方法。

但稍后也许您将需要管理事务。我认为将事务管理留给班级可以节省大量时间。这种情况最适合非静态类。

于 2009-03-12T08:50:41.393 回答