Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 数据库访问的全局属性,而不是到处传递数据库?有人建议吗?_Database_Vb.net_Ms Access_Properties_Global Variables - Fatal编程技术网

Database 数据库访问的全局属性,而不是到处传递数据库?有人建议吗?

Database 数据库访问的全局属性,而不是到处传递数据库?有人建议吗?,database,vb.net,ms-access,properties,global-variables,Database,Vb.net,Ms Access,Properties,Global Variables,地球人是邪恶的,对吗?至少我读到的每一篇文章都是这样说的,因为有些事情可能会在任何时候改变全球经济的状态 然而,我有一个DB对象,它在类参数方面有点杂乱无章。下面的属性是自动在MS Access或SQL中工作的包装类的实例,因此它不是EF或其他ORM Public Property db As New DBI.DBI(DBI.DBI.modeenum.access, String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}

地球人是邪恶的,对吗?至少我读到的每一篇文章都是这样说的,因为有些事情可能会在任何时候改变全球经济的状态

然而,我有一个DB对象,它在类参数方面有点杂乱无章。下面的属性是自动在MS Access或SQL中工作的包装类的实例,因此它不是EF或其他ORM

Public Property db As New DBI.DBI(DBI.DBI.modeenum.access, String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0} ;Persist Security Info=True;Jet OLEDB:Database Password=""lkjhgfds8928""", GetRpcd("c:\cms")))
代码本身确实有用于异常处理的PostSharp,因此我认为我可以有条件地处理oledb错误,方法是记录它们并在DB为Null时重新初始化它

到目前为止,解决方案是不断地将db作为参数传递给每个需要它的类。大多数数据类都有一个共享的observablecollection,它是从单独实现inotifyproperty changed的结构中构建的。其中一个是异步构建的。collection属性在触发私有异步buildCollection子类之前检查它是否为空

考虑到我们还没有使用依赖注入,我需要学习它;全球资产真的那么糟糕吗?在任何拉入或保存数据的地方都需要数据库。我唯一不需要它的地方就是视图和它背后的代码

这不是一个面向客户的项目,但它确实需要坚实


感谢您的建议

将DB连接作为参数传递到类中使用的是依赖项注入,也许您没有意识到它是这样的。在调用者中硬编码连接字符串仍然是没有依赖关系的代码,但至少您的数据库访问器本身没有对全局连接的依赖关系

Globals不仅仅是因为它们在未经通知的情况下发生了变化而变得邪恶——这只是您看到的由糟糕的设计选择导致的一种效果。它们是邪恶的,因为使用它们的设计是脆弱的。依赖于globals的代码需要在调用它之前正确设置不可见的内容,这会导致不相关代码之间的相互依赖。无形的东西变得至关重要。仅阅读内部使用globals的模块的接口,我如何知道在调用SetupGlobalThing()方法之前必须调用它?如果根据用户选择的函数,以不同的顺序调用IncrementGlobalThing()和DecrementGlobalThing()和MultiplyGlobalThing(),会发生什么情况

相反,您更喜欢无状态方法,在这种方法中,您可以传递所有要更改和使用的内容:IncrementThing(Integer thing)不依赖于隐藏的设置步骤。它显然做了一件事:增加传入的内容

从单元测试的角度考虑它可能会有所帮助。如果您要编写一个单元测试来证明特定的代码模块是有效的,那么您需要通过一个真实的数据库连接(硬*),还是能够通过一个可以轻松满足测试需要的假数据库引用

测试逻辑的最好方法是单元测试。测试类接口和方法结构的最佳方法是编写调用它们的单元测试。如果类很难测试,那么很可能是由于依赖于外部事物(全局、单例、数据库、不适当的成员变量等)

  • 我之所以称使用真正的数据库为“硬”的原因是单元测试需要简单快速地运行。它不应该依赖于缓慢、易碎或复杂的外部事物。考虑在没有网络连接的情况下,在总线上对软件进行单元测试。想想创建一个虚拟数据库需要做多少工作:你必须添加用户,必须在其中安装正确版本的模式,必须安装正确类型的测试数据,需要连接到它的网络,所有这些都会使你的测试不可靠。相反,在单元测试中,您传入一个模拟数据库,该数据库只返回用于测试代码的值

我通常只将连接字符串保留为全局值/设置。然后在需要时创建新的db对象。每次打开、查询、关闭和处置以避免问题。这不是您的选项吗?@WozzeC不像我使用wrapper db类那么容易,我在数据层的任何地方都需要一个实例。我的备选方案似乎是一个全局对象、每个数据类上的一个附加参数,或者在每个类中创建所述实例。从技术上讲,我认为后者是更好的实践,结合您建议的全局资源,因为至少我避免了tramp参数或全局邪恶。我只是不确定这是否是一种选择。其他人在处理ms access时会做什么?此时包装器是必需的。访问文件会随着版本号的变化而变化,因此发现功能会使简单的全局连接复杂化。如果您看到了我们目前的通用代码,您会理解为什么单元测试对我们来说实际上是不可能的。遗留类中的大多数构造函数都有大量参数,而不是推荐的0-3(Martin Fowler)。我个人已经运行了一两个单元测试来了解它们,但目前它们根本没有被使用。我希望我们的下一个架构设计将更加分层、组合和可测试,但这是我可以尝试应用我所有书籍中的内容的未来:)。现在,我正处于重构的老式代码的中间。全局DB是一个内容编辑器,只在内部使用,所以它确实很方便。如果我可以通过Aspects(PostSharp)安全地实例化它,那会很方便,但我认为建议使用资源字符串并在需要时实例化可能是我应该做的。非常感谢。