65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (3投票s)

2005年5月23日

3分钟阅读

viewsIcon

40052

downloadIcon

449

本文描述了如何构建可插拔数据访问组件。

引言

本文解释了如何构建更好的数据访问可插拔系统。我之前写的关于这个主题的文章不够灵活。我将所有功能硬编码到数据访问组件中。虽然这对于小型应用程序来说很好,但对于经常更改的大型应用程序来说,这完全是一场噩梦。

组件的目标

数据访问组件的目标应该是与数据库的通信。您如何构建您的业务逻辑并不重要,我认为数据访问层应该为您提供正确完成工作的工具。因此,它需要实现以下几点:

  1. 填充数据集
  2. 更新数据集
  3. 执行命令

总体设计

总体设计简单但非常灵活。所有类型的提供程序都有一个单一的接口,并且有一个工厂来生成提供程序。为了能够将单一类型的命令传递给数据访问,我创建了一个包装器。这个包装器只是一个带有属性的类,它本身并没有做太多事情。一旦我将命令传递给提供程序,它就会被翻译成该类型数据访问提供程序的特定命令。类图如下:

使用代码

要在您的应用程序中使用代码,您首先需要引用程序集。如果您使用 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 – 首次发布。
© . All rights reserved.