0

我有一个隐藏不同 ADO.NET 提供程序差异的 dll,并且有很多代码,例如:

private static void AppendProviderSpecificParameterCmdStr(StringBuilder sb, DbCommand cmd, string fieldNameToUse, ComparisonOperator oprtr, string parameterName)
{
    if (cmd is System.Data.OracleClient.OracleCommand || cmd is Oracle.DataAccess.Client.OracleCommand)
    {
        sb.AppendFormat("{0}{1}:{2}", fieldNameToUse, GetComparisonOperatorStr(oprtr, cmd), parameterName);
    }
    else if (cmd is SqlCommand)
    {
        sb.AppendFormat("{0}{1}@{2}", fieldNameToUse, GetComparisonOperatorStr(oprtr, cmd), parameterName);
    }
    else if (cmd is OleDbCommand)
    {
        sb.AppendFormat("{0}{1}?", fieldNameToUse, GetComparisonOperatorStr(oprtr, cmd));
    }
    else
    {
        throw new Exception(string.Format("Wrong database command type: {0},", cmd.GetType()));
    }
}

其中比较运算符是我自己的枚举。

Oracle.DataAccess 存在于所有具有 oracle 客户端的机器上,并且此代码可以满足我的需要。但是现在我遇到了只有 SqlClient 并且他们根本不需要 oracle 的情况。所以我的代码只有在我复制 Oracle.DataAccess.dll 时才有效,这自然是一个可怕的解决方案。这应该如何以正确的方式完成?

谢谢-马蒂

4

2 回答 2

1

我不会把对 dll 的依赖称为一个可怕的解决方案。您的解决方案支持 Oracle,因此您的解决方案中有一个 oracle dll - 它就是这样。

也就是说,您可以做一些事情来抽象出命令类型。

一 - 创建实现接口的完整数据访问方法。您当前的解决方案我将更多地归类为通用数据访问的帮助程序或实用程序方法。您可以改为声明一个特定于域的接口——例如客户——比如 ICustomerDA。在您的情况下,您将有 3 个 ICustomerDA.Insert 实现,其中隐藏了数据库细节。您的主要代码只需要了解 ICustomerDA。这可能是我在更大的解决方案中会做的事情,因为 RDBMS 之间的差异和特性远远超出了参数声明。

二 - 如果你想坚持更多的帮助/实用程序的想法,你可以为 db 对象的包装器创建一个接口,比如 IDBCommand。实现 IDBCommand 将隐藏底层命令对象,然后具有 .AppendProviderSpecificParameterCmdStr 方法的特定实现,该方法允许您执行以下操作:

OracleDbHelper : IDbCommand...
  public void AppendProviderSpecificParameterCmdStr(...){
    sb.AppendFormat("{0}{1}:{2}", fieldNameToUse, GetComparisonOperatorStr(oprtr, cmd), parameterName);
  }

IDBCommand cmd = DAFactory.GetCommand();
cmd.AppendProviderSpecificParameterCmdStr(...

这两种解决方案的关键是通过主项目中的公共接口而不是单个类型进行引用。一旦你这样做了,你可以在你的工厂中使用反射,或者更好,比如MEF来创建实际的类型。

于 2013-03-11T18:54:16.227 回答
0

所以我的代码只有在我复制 Oracle.DataAccess.dll 时才有效

除非您拥有本地 OCI DLL,例如因为您已经安装了 Oracle 客户端,否则不会。

为避免强制您的用户安装完整的 Oracle 客户端,您可以将来自 Oracle Instant Client 的 DLL 与应用程序一起分发。如果用户从不选择连接到 Oracle,则永远不会调用这些 DLL,它们只是静静地坐在那里而不会造成任何麻烦。

有关分发内容以及如何涵盖 32 位和 64 位的一些提示,请查看这篇文章

我们有一个自己开发的抽象层,目前可以与 Oracle 和 MS SQL Server 一起使用(并且可以移植到任何具有良好 ADO.NET 提供程序的 DBMS),并且该系统到目前为止运行良好。

于 2013-04-08T19:40:39.930 回答