简体   繁体   English

DbConnection 与 OleDbConnection 与 OdbcConnection

[英]DbConnection vs OleDbConnection vs OdbcConnection

What are the main advantages of each of the above database connection methods in C# in terms of connecting to multiple possible data sources (being database agnostic)?在连接到多个可能的数据源(与数据库无关)方面,C# 中上述每种数据库连接方法的主要优点是什么? Also in terms of performance which is likely to offer the best performance across the board?同样在性能方面,哪个可能提供全面的最佳性能?

Finally are there any reasons you would avoid a particular method for a database agnostic application?最后,对于与数据库无关的应用程序,您是否有任何理由避免使用特定方法?

The reason I ask is because my application currently uses Ole and I am having a few issues with connecting to certain databases using factories and as such am looking into alternatives.我问的原因是因为我的应用程序当前使用 Ole,并且我在使用工厂连接到某些数据库时遇到了一些问题,因此正在寻找替代方案。 I have heard Odbc is slower than Ole but is there any truth behind this and is it really noticeable in a real world application?我听说 Odbc 比 Ole 慢,但这背后有什么道理吗?它在现实世界的应用程序中真的很明显吗?

Reason for my interest in this subject is as follows:我对这个主题感兴趣的原因如下:

My requirements for my current project state that I must have a working data access layer that is capable of connecting to any database without prior knowledge of said database.我对当前项目 state 的要求是,我必须有一个工作数据访问层,能够连接到任何数据库,而无需事先了解所述数据库。 Therefore I cannot hard code anything specific for any given database in terms of connection.因此,就连接而言,我不能对任何给定数据库的任何特定内容进行硬编码。 Running dialect specific statements on each given database has been dealt with using an sql query factory type concept.已使用 sql 查询工厂类型概念处理在每个给定数据库上运行方言特定语句。 The same goes for substitution and formatting of bind variables.绑定变量的替换和格式化也是如此。

UPDATE: As it stands I now have a working version of my code which is using ADO.net and database provider factories.更新:就目前而言,我现在有一个使用 ADO.net 和数据库提供程序工厂的代码的工作版本。 This means I am using the base classes as suggested by Adam Houldsworth.这意味着我正在使用 Adam Houldsworth 建议的基类。 The provider is specified in the connection string under the providerName attribute.提供程序在 providerName 属性下的连接字符串中指定。 The connection string is stored in the app.config where it can be retrieved by my database connection class. Provided the correct driver has been installed such as npgsql or the odac package for Oracle then the factory will work fine.连接字符串存储在 app.config 中,可以通过我的数据库连接 class 检索它。如果安装了正确的驱动程序,例如 npgsql 或 Oracle 的 odac package,那么工厂将正常工作。 Below is a sample of my code showing the basic constructor for a connection object using a provider factory.下面是我的代码示例,显示了使用提供程序工厂的连接 object 的基本构造函数。

private readonly DbFactoryBindVariables m_bindVariables;
private readonly DbProviderFactory m_provider;
private string m_connectionString = String.Empty;
private readonly string m_providerName = String.Empty;
private DbConnection m_dbFactoryDatabaseConnection;


/// <summary>
/// Default constructor for DbFactoryDatabaseConnection.
/// </summary>
public DbProviderFactoryConnection()
{
        m_providerName = ConfigurationManager.ConnectionStrings["ApplicationDefault"].ProviderName;
        m_provider = DbProviderFactories.GetFactory(m_providerName);

        m_dbFactoryDatabaseConnection = m_provider.CreateConnection();

        m_connectionString = ConfigurationManager.ConnectionStrings["ApplicationDefault"].ConnectionString;
        m_dbFactoryDatabaseConnection.ConnectionString = m_connectionString;

        m_bindVariables = new DbFactoryBindVariables(m_dialect.ToLower(), DbFactoryBindSyntaxLoader.Load(this));
}

It may be required to add something similar to the following into the app.config or web.config if it is not already present in the machine.config for your chosen .net framework version.如果您选择的 .net 框架版本的 machine.config 中尚未存在,则可能需要将类似于以下内容的内容添加到 app.config 或 web.config 中。

<system.data>
    <DbProviderFactories>
       <add name="Npgsql Data Provider" 
        invariant="Npgsql" 
        support="FF" 
        description=".Net Framework Data Provider for Postgresql Server"
        type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.1.0, Culture=neutral, 
        PublicKeyToken=5d8b90d52f46fda7" />
    </DbProviderFactories>
</system.data>

Connection string required:需要连接字符串:

<add name="ApplicationDefault" connectionString="DATA SOURCE=TNSNAME;PASSWORD=PASS;USER ID=USER;" providerName="Oracle.DataAccess.Client;"/>

At this stage I can now be totally database agnostic provided the correct connection string is used when configuring the clients version of the application.在这个阶段,如果在配置应用程序的客户端版本时使用了正确的连接字符串,我现在可以完全与数据库无关。

I would avoid abstracting the connection to the database as you are always targeting the lowest common denominator.我会避免抽象化与数据库的连接,因为您始终以最低公分母为目标。 Instead, try to abstract the requirement of saving the entities.相反,尝试抽象保存实体的要求。 Each implementation of that abstraction can then be database specific (basically, programming against interfaces).然后,该抽象的每个实现都可以是特定于数据库的(基本上,针对接口进行编程)。

That said, I have not once experienced an instance where needing to support multiple databases was a hard requirement.也就是说,我还没有遇到过需要支持多个数据库是一项硬性要求的实例。 In this case, all this aggravation runs into the YAGNI mantra.在这种情况下,所有这些恶化都会遇到 YAGNI 咒语。

An question on comparing OLE DB to ODBC generally can be found here:通常可以在此处找到有关将 OLE DB 与 ODBC 进行比较的问题:

what is the difference between OLE DB and ODBC data sources? OLE DB 和 ODBC 数据源有什么区别?

Although asking the performance questions upfront is a good thing, the question cannot be answered in the context of your application.虽然提前询问性能问题是一件好事,但在您的应用程序上下文中无法回答该问题。 Unfortunately, only profiling of both against sample data will give you the answers you need.不幸的是,只有根据示例数据对两者进行分析才能为您提供所需的答案。

There isn't much to note about DbConnection , it is the base class to the other database-specific connection classes.关于DbConnection没有太多需要注意的地方,它是其他特定于数据库的连接类的基础 class。

Have you considered an ORM like NHibernate or a framework like the Enterprise Library Data Access Application Block ?您是否考虑过像 NHibernate 这样的 ORM 或像Enterprise Library Data Access Application Block这样的框架? These will help you abstract the database (with ORMs, to the point where you don't even need to do any coding in the database).这些将帮助您抽象数据库(使用 ORM,甚至不需要在数据库中进行任何编码)。

Update: so far as I can tell from the comments it appears as though your only option is to use the .NET base classes provided (such as DbConnection ) or the interfaces ( IDbConnection ).更新:据我从评论中可以看出,您唯一的选择似乎是使用提供的 .NET 基类(例如DbConnection )或接口( IDbConnection )。 To my knowledge there isn't anything that can give you the correct connection for a connection string, so you may have to code that part.据我所知,没有任何东西可以为连接字符串提供正确的连接,因此您可能必须对该部分进行编码。 This way, you can return an OleDbConnection , OdbcConnection , SqlConnection , etc when you detect the connection string, but use them in code as DbConnection or IDbConnection , thus keeping your code agnostic of the underlying database.这样,您可以在检测到连接字符串时返回OleDbConnectionOdbcConnectionSqlConnection等,但在代码中将它们用作DbConnectionIDbConnection ,从而使您的代码与底层数据库无关。

Not ideal, but perfectly workable.不理想,但完全可行。

Using DbProviderFactory is a good choice if you need to have an agnostic data access layer, without coding the data access more than once.如果您需要一个不可知的数据访问层,而不需要多次对数据访问进行编码,那么使用DbProviderFactory是一个不错的选择。

I don't see any reason you want to avoid it and all the necessary functionality is covered using the base classes on System.Data.Common .我看不出有任何理由要避免它,并且使用System.Data.Common上的基类涵盖了所有必要的功能。

We are using a agnostic data access on Nearforums because we deliver both SQL Server and MySql db scripts.我们在Nearforums上使用不可知的数据访问,因为我们同时提供 SQL 服务器和 MySql 数据库脚本。 About performance, it depends on the specific connector (Oracle, MySql, PostgreSQL, ...) implementations delivered by the different companies / communities.关于性能,它取决于不同公司/社区提供的特定连接器(Oracle、MySql、PostgreSQL,...)实施。 Most known connectors had been properly tested during several years.大多数已知的连接器都经过了几年的适当测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM