BooProd.Core - 上下文敏感的连接字符串






3.83/5 (4投票s)
2004年12月13日
8分钟阅读

44068

263
本文旨在帮助您创建上下文敏感的连接字符串:动态选择,取决于应用程序运行在哪个服务器上。
引言
本文的目的是帮助 .NET 开发者在不使用高级嵌入式 .NET 组件的情况下访问 SQL Server 数据库。您可以在这里找到一个简单的 XML 配置文件,用于定义您自己的上下文敏感的数据库连接,以及易于使用的模板,用于访问 SQL Server 存储过程和检索数据。该软件包可以为您节省大量构建新数据库应用程序的时间。
什么是上下文敏感的数据库连接?
当您在本地计算机上创建数据库应用程序时,您使用连接字符串来访问数据库。当您尝试将应用程序部署到 Internet 时(无论它是 Web 应用程序还是其他类型的应用程序),都会出现一个大问题。您的所有连接字符串都指向您的本地数据库服务器,而不是您的生产数据库服务器。解决方案是重写所有连接字符串。我开玩笑的,这并不明智!事实上,您需要动态选择这些连接字符串,具体取决于应用程序运行在哪个服务器上。这就是我所说的上下文敏感的数据库连接。
背景
使用此软件包无需任何背景知识。只需打开您的 Visual Studio .NET,然后创建一个新解决方案。然后将 BooProd.Core
项目添加为现有项目。创建您的新 Windows C# 应用程序,并将此项目作为引用添加。然后,请参阅下面的代码使用说明。我希望您也有一个可以访问的 SQL Server 2000 数据库 :-)
使用代码
本文的目的是帮助您在 C# 应用程序中使用 SQL Server 数据库。首先,我们需要配置 SQL Server 连接并初始化软件包以便使用它。然后,我们将看到一些显式访问数据库的方法:插入数据、检索数据、获取存储过程结果。
本地 vs 生产
此软件包的主要功能之一是基于对执行上下文的检测。我认为,在项目的生命周期中,有两个主要阶段。第一阶段是在您的本地计算机上创建项目(图中的“我的办公室”)。第二阶段是将项目从本地计算机部署到您的生产服务器(图中的“我的托管位置”)。有时会有一个预生产服务器,但我们会将其视为生产服务器。在本地版本和生产版本的文件之间,修改越少越好。此软件包的目的是在本地版本和生产版本之间实现零修改。
为了使用上下文敏感的信息,我们需要在执行时知道我们是在本地执行上下文还是在生产执行上下文中。我将上下文检测建立在执行应用程序的主机 IP 地址上。当您在本地计算机上工作时,您通常在一个私有网络中,并且您的计算机的 IP 地址例如是 10.1.1.1。假设您与团队中的另一位同事一起工作,其主机 IP 地址配置为 10.1.1.2。您都需要被视为在本地上下文中执行项目。因此,我将定义您和他之间的常见IP 前缀为“10.1.1.”。所有以“10.1.1.”开头的 IP 地址都将被视为在本地上下文中执行,而所有其他 IP 地址都将被视为在生产上下文中执行。例如,具有私有 IP 地址“10.2.2.1”或公共 IP 地址“192.248.1.10”的主机将被视为在生产上下文中执行。
配置
首先要做的是用您自己的数据库参数填充 XML config 文件。该文件的模板在 BooProd.Core 项目中,名为 ExeContextTemplate.xml。ExeContext 代表 execution context(执行上下文)。将此文件复制到您的项目根目录。
第一个 XML 节点是 ExeConfig
。version
属性用于 XML 文件的版本控制,以供将来使用并检查兼容性。local_ip
属性允许确定所有被视为本地的 IP 地址的前缀。
下一个 XML 节点是 ExeDBList
,它描述了上下文敏感的数据库连接到您的数据库。每个数据库连接都通过一个 ExeDB
节点进行详细说明。alias
属性是一个关键字(别名),在您的 C# 代码中每次需要访问数据库时都会使用它。ConnectionString
属性是用于访问数据库的连接字符串,具体取决于本地或生产执行上下文。您可以根据需要放置任意数量的 ExeDB
节点。
...
<ExeConfig>
<version>1.2</version>
<local_ip>10.1.</local_ip>
</ExeConfig>
<ExeDBList>
<ExeDB>
<alias>BOOPROD</alias>
<local><ConnectionString>data source=10.1.5.5,1136;
initial catalog=BOOPROD_PROJECT;user id=boologin;password=boopwd;
persist security info=True</ConnectionString></local>
<prod><ConnectionString/></prod>
</ExeDB>
</ExeDBList>
...
动态 vs 静态访问
动态访问
访问值的第一个方法是提供 XML config 文件中定义的关联别名字符串,如下所示
ExeContext.WebSite("CODEPROJECT").URL
这将返回与 XML config 文件中定义的“CODEPROJECT”别名关联的网站 URL。这效果很好,但您可能会拼写错误别名,并且可能难以调试。
静态访问
另一种方法更快捷、更安全。与 ExeContextTemplate.xml 一起提供了一个 ExecTemplate.cs 类。这个类充当 XML config 文件中定义的值的直接快捷方式。这更安全,因为您可以在编译时检查所有别名是否有效,从而验证关联的信息。此方法的缺点是您必须编写一个小型类,并且所有别名都必须映射到 XML config 文件。但是,访问信息将是最快的。
ExecTemplate.WS_CODEPROJECT.URL
这将返回与 XML config 文件中定义的“CODEPROJECT”别名关联的网站 URL,使用 ExecTempate
类的 XS_CODPROJECT
属性。
初始化
创建配置表之后,在使用该程序包之前需要对其进行初始化。您只需要执行一次。最好的方法是在应用程序的主构造函数窗体中进行。
public MainForm()
{
InitializeComponent();
ExecTemplate.autoInit();
}
执行
现在,您已准备好访问 SQL Server 数据库。ZIP 文件中包含的 TestDBAccess
项目将向您展示访问数据的不同方法。使用 ExeContext.xml 的 BOOPROD 别名配置访问有效本地数据库所需的信息。然后使用 DB.txt 文件创建 BOOPROD_PROJECT 数据库、表和 SQL 存储过程。您可以启动 TestDBAccess
演示应用程序并尽情体验。
此演示应用程序不是登录窗口,它只是展示如何将值(“Login”字段)插入数据库,查找值(“Login”字段)是否存在于数据库中,以及从数据库中显示值列表(“List field”)。错误代码显示在相应的字段中。这些是所有数据库项目中常用的函数。
如果您对使用我的程序包访问数据库不感兴趣,而仅仅是为了拥有上下文敏感的数据库连接,那么静态方法 ExeContext.DB("BOOPROD")
将为您提供解决方案;只需将“BOOPROD”替换为您 XML 数据库别名即可。别忘了在此之前进行初始化。
execQuerySPR
执行一个存储过程并获取返回值。此示例向您展示如何调用一个返回结果集并返回一个指示是否存在错误的错误码的存储过程。这对于将数据插入数据库并告知用户错误非常有用。
...
QConnection vQConnection= new QConnection(ExeContext.DB("BOOPROD"));
vQConnection.addVarChar ("@pBLOGIN_login", pLogin);
vQConnection.addVarChar ("@pBLOGIN_password", pPassword);
SqlCommand vCommand= vQConnection.execQuerySPR("[BLOGIN_newFromLoginPassword]");
SqlDataReader vReader= vCommand.ExecuteReader();
BLogin vBLogin= new BLogin();
if (!vBLogin.read(vReader))
vBLogin= null;
vReader.Close();
pResult= (int)(vCommand.Parameters["ReturnValue"].Value);
vQConnection.closeConnection();
...
execQuerySP
执行一个存储过程。此示例代码向您展示如何调用一个返回结果集的存储过程。这对于从数据库获取数据非常有用。
...
QConnection vQConnection= new QConnection(ExeContext.DB("BOOPROD"));
vQConnection.addVarChar("@pBLOGIN_login", pLogin);
vQConnection.addVarChar("@pBLOGIN_password", pPassword);
SqlDataReader vReader= vQConnection.execQuerySP("[BLOGIN_getWithLoginPassword]");
BLogin vBLogin= new BLogin();
if (!vBLogin.read(vReader))
vBLogin= null;
vReader.Close();
vQConnection.closeConnection();
return vBLogin;
...
UML 考虑
不用担心 UML,它非常酷。您不需要通读本节,关键信息已包含在演示项目中。
这是主要的 ExeContext
类以及直接访问类 ExecTemplate
。
使用 QConnection
类,您只需使用带由 ExecTemplate
类提供的正确 ExeDB
实例的构造函数,然后使用add 方法添加参数到查询,最后是query 方法本身。
关注点
- 首先,也许您并不真正理解为什么要将数据库访问封装到一个新程序包中?我的感觉是,当您在一个团队中工作时,每个人都必须遵循相同的开发规则。所以,这是一种做到这一点的方法。
- 此程序包将在本地和生产环境中无需修改即可自行执行。这非常酷。
- 此程序包是可扩展的,因为我在
QConnection
类中只实现了一些有用的类型。请随时添加您自己的数据库类型。
历史
这是我的第一篇文章,但在我接下来的文章中(希望很快就会发布),您将发现该程序包的一些惊人功能,例如上下文相关的数据库连接,以及动态计算网站 URL,这在生命周期开发中非常有用……我还会展示我自己的代码编写规则,用于创建数据库映射对象。
- v1.2 - 2004/12/07
重写了文章介绍,以更精确地说明目的。新的 XML 文件直接访问。
- v1.1 - 2004/11/19
由于 XML 文件的一些限制,我现在使用完整的
ConnectionString
。在 XML 文件中添加了注释并升级了版本。 - v1.0 - 2004/11/15
First version.