可插入的数据访问组件 - 第2部分





4.00/5 (3投票s)
2005年5月23日
3分钟阅读

40052

449
本文描述了如何构建可插拔数据访问组件。
引言
本文解释了如何构建更好的数据访问可插拔系统。我之前写的关于这个主题的文章不够灵活。我将所有功能硬编码到数据访问组件中。虽然这对于小型应用程序来说很好,但对于经常更改的大型应用程序来说,这完全是一场噩梦。
组件的目标
数据访问组件的目标应该是与数据库的通信。您如何构建您的业务逻辑并不重要,我认为数据访问层应该为您提供正确完成工作的工具。因此,它需要实现以下几点:
- 填充数据集
- 更新数据集
- 执行命令
总体设计
总体设计简单但非常灵活。所有类型的提供程序都有一个单一的接口,并且有一个工厂来生成提供程序。为了能够将单一类型的命令传递给数据访问,我创建了一个包装器。这个包装器只是一个带有属性的类,它本身并没有做太多事情。一旦我将命令传递给提供程序,它就会被翻译成该类型数据访问提供程序的特定命令。类图如下:
使用代码
要在您的应用程序中使用代码,您首先需要引用程序集。如果您使用 Visual Studio .NET,这应该不是什么大问题。之后,您就可以立即开始工作。
开始与数据库的会话
要开始一个新的数据库会话,您需要一段如下所示的代码:
DatabaseSessionFactory factory = new DatabaseSessionFactory();
factory.DriverType = "SQL";
factory.ConnectionString =
"Server=(local');Database=Store;Integrated Security=SSPI";
DatabaseSession session = factory.BeginSession();
执行命令
创建新会话后,您可以开始填充或更新数据集、执行命令等。一个示例显示如下:
DatabaseCommand cmd = new
DatabaseCommand("SELECT * FROM Employees WHERE Name = @Name");
cmd.Parameters.Add(new CommandParameter("@Name","Some name",
ParameterType.Input);
IDataReader reader = session.ExecuteQuery(cmd);
所有参数(无论哪个提供程序)都应该具有 @<ParamName>
格式。虽然一些提供程序需要 ?<ParamName>
甚至没有名称,但提供程序将在内部解决这些问题。
关注点
在编写这段代码时,我发现 OleDB 是一个相当奇怪的提供程序。特别是对于 Access 数据库。参数按索引而不是按名称使用。这意味着我遇到了这个提供程序的问题,因为我按名称工作。我通过在将命令翻译为特定的 OleDbCommand
时修复命令参数的索引来解决这个问题。
//Place all the parameters in the right order
Regex regex = new Regex(@"@(\S+)");
MatchCollection matches = regex.Matches(cmd.CommandText);
foreach(Match m in matches)
{
foreach(CommandParameter param in command.Parameters)
{
if(param.Name == m.Value)
{
//Remove the @ sign at the beginning
//of the parametername
//when adding it to the command
OleDbParameter parameter = new OleDbParameter(
param.Name.Substring(1),param.Value);
parameter.Direction = param.Type;
cmd.Parameters.Add(parameter);
cmd.CommandText = cmd.CommandText.Replace(m.Value, “?”);
}
}
}
程序集包含的 MySQL 提供程序也存在一些问题。参数按名称排列,但前缀与我在接口中使用的 @ 符号不同。这修复起来相当简单,我将前缀替换为一个问号,它是 MySQL 参数的前缀。
改进之处
我对 FillDataSet
方法不是很满意,它们倾向于添加像 Table1、Table2、Table ... 等表。这不是我想发生的事情。所以我添加了带有 table 参数的 FillDataSet
方法。这是一个丑陋的解决方案,因为我认为它可以用更优雅的方式解决。欢迎就此提出想法!
另一个可以改进的地方是工厂类的设置。应该可以根据工厂类中配置的参数构建连接字符串。这应该发生在 DatabaseSession
实现类中。也许我会在下一个版本中解决这个问题。
文档并不总是与实际实现相符。虽然这只是一些示例,但应该在下一个版本中解决。
结论
此版本的可插拔数据访问组件比我编写的旧实现好得多。它更具可扩展性,并且比旧版本更容易使用。我希望阅读这篇文章的人会同意我的观点。
历史
- 2005/5/23 – 首次发布。