【问题标题】:IdbConnection vs. SqlConnectionIdbConnection 与 SqlConnection
【发布时间】:2008-12-08 19:38:03
【问题描述】:

当我编写应用程序时,我使用 System.Data 接口(IDbConnection、IDbCommand、IDataReader、IDbDataParameter 等...)。我这样做是为了减少对供应商的依赖。除非,我正在做一个简单的测试应用程序,否则在咨询时这似乎是合乎道德的事情。

但是,我看到的所有代码似乎都使用 System.Data.SqlClient 命名空间类或其他供应商特定类。在杂志和书籍中,很容易将其归结为 Microsoft 的影响力和他们的营销策略,只针对 SQLServer 进行编程。但它看起来就像我看到的几乎所有 .NET 代码都使用 SQLServer 特定的类。

我意识到供应商特定的类具有更多功能,例如向 SqlCommand 对象添加参数是一种方法,而将其添加到 IDbCommand 则需要 4 多行代码。但话又说回来;为这些限制编写一个小助手类非常简单。

我还想知道当 SQLServer 是当前目标客户端时针对接口进行编程是否过度设计,因为它不是立即需要的。但我不认为这是因为针对接口进行编程的成本如此之低,而减少供应商依赖性会带来如此巨大的好处。

您是否使用供应商特定的数据类或接口?

编辑:总结下面的一些答案,并提出我在阅读它们时的一些想法。

使用接口实现供应商中立性的可能陷阱:

  • 嵌入的供应商特定关键字 你的 SELECT 语句(我所有的 ins, upd 和 del 都在 procs 中,所以这是 没问题)
  • 直接绑定 数据库可能会导致 问题。
  • 除非你的连接 实例化是集中的, 供应商特定类将需要 无论如何都会被调用。

使用接口的积极原因:

  • 根据我的经验,能力(甚至 如果不行使)移动到 不同的供应商一直是 深受客户好评。
  • 在可重用代码库中使用接口

【问题讨论】:

    标签: .net design-decisions vendor-neutrality


    【解决方案1】:

    要考虑的一件事是您切换数据库的实际机会。在大多数情况下,这永远不会发生。即使是这样,这也将是一次重大的重写,即使您使用与数据库无关的类。在这种情况下,最好使用功能更丰富且能帮助您更快完成项目的那个。

    话虽如此,我认为在大多数情况下,您应该使用自己创建的层,在实际的 .Net API 之上,这样如果您必须更改必须使用的类,那么它就不会这么大的问题。即使您留在同一个数据库上,您也永远不知道何时必须切换访问数据库的方式。任何从 ASP 迁移到 ASP.Net(ADODB 与 ADO.Net)的人都可以告诉您这是多么痛苦。

    所以我认为最好的解决方案是使用功能更丰富的数据库特定 API,并在其之上构建您自己的层,以便您可以在必要时轻松将其替换掉。

    【讨论】:

    • 我非常不同意它必须是一个重大的重写。至少,所有数据库对象都必须进行调整,但是如果您使用接口并且不使用供应商特定的关键字,我认为您的 .NET 代码不需要进行太多更改。至于数据层的想法,我同意。
    • 供应商有特定的关键字是有原因的。它们是集成的,速度很快,而且做的事情很酷。想象一下,如果“Order by”是特定于供应商的。你编写一个客户端排序因为你想不可知论。尽可能不使用供应商特定的“order by”是个傻瓜。
    • 对于端到端应用程序,这可能是正确的,但对于可能支持多个供应商的第 3 方插件或同时使用多个供应商的应用程序来说,情况并非如此
    【解决方案2】:

    您必须为类提供的 SQL 有所不同,具体取决于您正在与之交谈的数据库引擎的类型,因此即使您设法编写了所有代码来使用接口,您仍然需要编写多组SQL。

    或者,你可以做我们所做的,编写我们自己的层来处理我们使用的所有语法,这不是不同引擎提供的所有语法,但足以设法编写一个 SQL 来获取在执行前正确重写。

    基本上,我们已经创建了一个函数语法,我们在函数名称前加上SQL::,这样我们的代码就可以识别需要重写的特殊函数。然后将它们解析出来并正确重写,甚至在必要时交换参数顺序。

    可以做一些小的事情,比如返回当前服务器日期和时间的函数名称,但也可以做更大的事情,比如如何选择查询的前 N ​​行。

    此外,SQL Server 的参数写为@name,其中 OleDb 使用位置(只需在需要参数的位置添加 ?),我们的代码也处理这些差异。

    从某种意义上说,我们不必太担心需要编写的 SQL。

    【讨论】:

    • db 对象至少需要进行“调整”。但我没有考虑 SQL 中的优化和供应商特定关键字。另外,在您提到的语法层中,这是否编写了您的 SQL?如果是这样,它是否得到了回报,我以前从未得到过回报。
    【解决方案3】:

    我正在写一些类似于 lassevk 所说的东西,但他比我更胜一筹。

    另外,你必须在某个时候与真实的数据库对话。您可能能够摆脱使用接口代码包装大部分数据访问,这是一个好主意。但最终,如果您使用的是 SQL Server,您将希望创建一个真实的 SqlClient.SqlConnection 实例。 Access、Oracle 或 MySQL 也是如此。

    【讨论】:

    • 同意。您确实需要在某个地方调用特定于供应商的类,但如果您将它放在一个集中位置,那么它确实会显着减少对移植所需的更改。
    【解决方案4】:

    您应该尝试编写与数据库无关的代码。也许你现在不觉得它有用,但你将来可能会利用它。

    【讨论】:

    • 与数据库无关的代码在每个数据库上都会很糟糕。数据库不是“即插即用”,它们是完全不同的野兽,需要不同的照顾和喂养。
    • 如果您为特定数据库编写不可知的代码和自定义驱动程序,那么您可以充分利用每一个。当然,这取决于项目,但我认为值得付出努力。例如,我多次从 Sql Compact 切换到 MySQL 或 Sql Server。
    【解决方案5】:

    我在直接进行数据库工作的地方使用供应商特定的类(除非我被告知我们最终可能会使用不同的数据库 - 发生的次数:一次)。

    但是,如果我最终将一些非 db 特定代码分解为单独的类,我通常会创建方法参数接口 - 特别是如果我认为它在其他项目中有用,并且我不依赖任何直接访问类的具体功能。

    基本上,套用爱因斯坦的话说:使解决方案尽可能简单,但不要更简单。

    【讨论】:

    • 最初,这就是我这样做的原因,为了一个可重用的库,然后我想,我应该在整个应用程序中都这样做,并且从那以后一直在使用它。为了简单起见,就像我之前说的,恕我直言,成本不会太高。
    【解决方案6】:

    查看 Microsoft 的模式和实践组的企业库。 他们那里的数据访问代码显示了提供者独立性的一些良好实现。

    http://msdn.microsoft.com/en-us/library/cc467894.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-10
      相关资源
      最近更新 更多