保持应用程序数据库不可知(ADO.NET与封装DB逻辑)

时间:2010-06-20 19:17:01

标签: c# mysql database oracle oledb

我们正在制作一个相当严肃的应用程序,需要与客户想要使用的数据库保持无关。最初我们计划支持MySQL,Oracle& SQL Server。表&视图很简单,查询也很简单(没有真正奇特的SQL),因此问题是:

  1. 使用本机数据库驱动程序(MySQLDbConnection等)并封装执行查询和处理结果的逻辑或
  2. 使用通用的OleDbConnection
  3. 显然,选项2不涉及开销,但我认为性能不如原生访问那么好?

8 个答案:

答案 0 :(得分:11)

  

注意:如果您决定使用基本的ADO.NET 2功能而不是ORM(例如Entity Framework或NHibernate)或LINQ to SQL,那么这个答案是相关的。

假设您在app.config

中定义了连接字符串
<connectionStrings>
    <add name="SomeConnection"
         providerName="System.Data.SqlClient"
         connectionString="..." />
</connectionStrings>

注意providerName属性及其值的存在。您还可以为另一个数据库提供程序输入一个值,例如System.Data.SQLite

(请注意,非标准提供程序,即默认情况下不在.NET Framework中的提供程序,need to be registered首先在app.config或客户端计算机的machine.config中。)

现在,您可以使用与提供程序无关的完全方式使用指定的数据库,如下所示:

using System.Configuration;  // for ConfigurationManager
using System.Data;           // for all interface types
using System.Data.Common;    // for DbProviderFactories

var cs = ConfigurationManager.ConnectionStrings["SomeConnection"];
//                                              ^^^^^^^^^^^^^^^^

var factory = DbProviderFactories.GetFactory(cs.ProviderName);
//                                           ^^^^^^^^^^^^^^^

using (IDbConnection connection = factory.CreateConnection())
{
    connection.ConnectionString = cs.ConnectionString;
    //                            ^^^^^^^^^^^^^^^^^^^
    connection.Open();
    try
    {
        using (IDbCommand command = connection.CreateCommand())
        {
            ...  // do something with the database
        }
    }
    finally
    {
        connection.Close();
    }
}

请注意此代码仅适用于接口类型。您指定特定数据库提供程序的唯一位置是providerName文件中的app.config属性值。 (我已用app.config标记^^^设置的所有地点。)


进一步阅读:

答案 1 :(得分:7)

使用ORM的IMHO是一个很好的设计决策,以便拥有一个与数据库无关的应用程序。切换数据库可能就像更改配置设置和连接字符串一样简单。

答案 2 :(得分:4)

您不需要OleDbConnection来访问非特定的ADO.NET提供程序。只需使用DbConnection et。人。有关详细信息,请参阅DbProviderFactories on MSDN

答案 3 :(得分:3)

通过在该列表中包含Oracle,您可以保证一切都不会那么简单。

  • 与使用“at”符号的SQL Server相比,Oracle对参数使用不同的前缀字符(冒号)。
  • Oracle对long,int,short,boolean,float和decimal使用单个数据类型(数字);您的代码必须确保正确映射这些代码。
  • 您必须参数化Oracle日期和时间值;如果您尝试在SQL语句中使用字符串作为日期,那么由于Oracle的日期格式,您将会疯狂。 (Oracle使用三个字符的月份缩写;格式为01-JAN-2010。)
  • 用于处理空值的基本SQL函数可能不同,尤其是对于空合并。 (“NVL”与“COALESCE”)Oracle对保留字的反应更为敏捷。
  • Oracle没有本机标识列支持。解决方法涉及序列,触发器和要求事务只是为了从新行检索标识值。

换句话说,您的应用无法与数据库无关。如果您不使用ORM,您肯定希望构建一个数据访问层,从应用程序的其余部分隐藏所有这些内容。

这里的经验之谈。只是在说'。对于跨SQL Server和Oracle的通用模式,我们必须构建ORM的大部分基础结构,同时避免可能降低性能的方面。有趣但非平凡,绝对是!

答案 4 :(得分:2)

LINQ是备受推崇的.NET ORM,部分原因是您可以使用它和存储过程。问题是,它只是SQL Server,但是人们正致力于为Oracle&amp;提供类似的功能。 MySQL

对于数据库&amp;查询优化,我对使用ORM的想法感到畏缩。数据类型,功能和整体语法在SQL中不是很容易移植。与每个数据库交互的最高效的方法是定制模型和模型。查询每一个,但它意味着专业知识,时间和金钱。如果需要,请关注一个具有代码设置的数据库供应商,以支持供应商交换&amp;根据需要添加对其他数据库的支持。

答案 5 :(得分:0)

没有充分的理由避免使用最广泛支持的最通用的接口 - OleDb甚至是ODBC,如果你对它们感到满意的话。除此之外的任何东西都会减少您可以使用的产品/语言/平台/工具/开发人员库。由于最接近SQL金属,供应商不会引入太多低效率 - 肯定比更深奥的选择更少。他们已经花了很长时间来解决任何问题。

如果你要添加一个抽象层(你自己或别人的),那么这应该根据你特定上下文中引入的抽象的优点来决定,而不仅仅是有一个抽象层(它只是除非有故意的好处,否则会得到更多的支持。)

如您所见,每个人的里程各不相同。 :)但总的来说,我认为更简单更好。

答案 6 :(得分:0)

为什么不使用Microsoft 模式&amp;实践 Enterprise Library数据访问应用程序块。最小的开销和交换提供商非常容易。

引用:

  

数据访问应用程序块   利用这些课程和   提供进一步支持的模型   封装数据库   特定于类型的功能,例如   参数发现和类型   转换。因为这,   应用程序可以从一个移植   数据库类型到另一个没有   修改客户端代码。

答案 7 :(得分:0)

通过让大量应用程序将DAL用作一堆接口,您始终可以使应用程序数据库的一部分不可知。然后,DAL本身将为目标数据库提供具体实现。

通过这种方式,您可以在DAL的使用中脱钩,但是DAL中的性能改进或供应商特定构造的好处。