复杂共享/静态成员的最佳实践

时间:2011-09-07 18:53:09

标签: c# .net asp.net vb.net static

我接管了一个ASP.NET应用程序,并在应用程序的几个类中找到了它。程序员在定义了几个共享/静态变量之前,这些变量在整个应用程序中充当“复杂的枚举”。作为一个相当新的程序员,它看起来不是最佳实践。

以下是一个例子:

Public Shared SecureCommentsWrite As New Task("Secure Comments Write")
Public Shared SecureCommentsRead As New Task("Secure Comments Read")
Public Shared EditEmergencyContact As New Task("Edit Emergency Contact")
Public Shared DisplayPersonalReferences As New Task("Display Personal References")
Public Shared EditPersonalReferences As New Task("Edit Personal References")

构造函数接受描述,然后使用存储过程从数据库加载ID密钥(数据库是SQL Server。)这似乎是一个好主意,因为我们将此应用程序部署到多个数据库并希望确保我们加载该数据库中的ID密钥,以防它发生变化。但是,由于应用程序中有数百个,因此第一次加载需要一段时间。

这被认为是最佳做法,如果不是,对于这样的情况,什么被认为是最佳做法?

4 个答案:

答案 0 :(得分:1)

对我来说,这是一种可怕的做法,如果你告诉我上面的每一行和Task构造函数都会调用一个单独的存储过程(即使存储相同的存储过程)。

在这种情况下的最佳实践是重构,对该存储过程进行单个调用并修改它以返回所有ID和名称,然后使用一个小的TaskManager或TaskLoader(无论)类来映射存储的结果并创建所有这些没有进一步数据库参与的元素。

在这些情况下,请注意SqlDataReader可能比DataSet更好,因为您只需要转发,只读快速访问数据。

现在一切都在我身边;-)

答案 1 :(得分:0)

你可能想要一个工厂类(TaskFactory?)。

它应该加载(一次)表示整个Task项列表的DataTable或DataSet。这可以由构造函数完成,或者[lazily]在执行第一个实例请求时完成。

然后工厂的CreateInstance()方法应该查询预加载的数据,而不是每次点击数据库。

答案 2 :(得分:0)

在对象构造函数或任何其他可能耗时的操作中运行数据库查询/存储过程不是一个好习惯。 如果在初始化Task对象期间出现问题,由于它被声明为静态/共享成员,它可能会抛出TypeInitializationException,您的应用程序将变得无法使用。

我会将这些成员视为某种应用程序配置。在Application_Start期间执行存储过程,它将立即(而不是逐个)带来所有数据,并创建配置对象。

答案 3 :(得分:0)

拥有代表常量值的静态字段列表没有任何内在错误;正如你所指出的那样,它与枚举基本相同,微软已经在自己的一些库中完成了它。

也就是说,如果初始化这些字段会导致明显的减速(并且由于它们每个都在命中数据库,这并不奇怪),可以使用一些技术来改善加载时间。一个显而易见的解决方案是使用延迟加载 - 换句话说,在你绝对必须之前不要打到数据库!这基本上可以分摊在数据库整个生命周期内命中数据库以初始化这些字段的成本,从而为您提供更快的启动速度,以换取其他地方稍慢的性能。

当然,如果你不得不一次懒加载100或1000,这可能也不是理想的解决方案;在这种情况下,你只是将大规模的延迟推迟了,而不是将其分解。

另一个想法是提高负责检索这些ID的SQL的效率。您可以编写一个Initialize()方法来执行单个查询,以便一次性提取所需的所有ID,而不是在100个不同的查询中执行。这几乎肯定会更快。