C# - 通用数据库连接,命令,阅读器的类

时间:2009-07-10 05:15:55

标签: c# ado.net

假设我正在设计一个可以处理任何数据库技术的类来创建连接,执行命令和检索数据等。

如果我需要为现有的RDBMS(如SQL Server,Oracle,FireBird等)创建一个通用的数据库处理类,我应该使用.net abstract-class / Interface {DbConnection,DbCommand,DbParameter,... }或{IDbConnection,IDbCommand,IDbParameter,...}?

我应该使用像

这样的代码吗?
public bool CreateConnection(DatabaseTypeEnum type)
{
    DbConnection conn ;

    if(type==DatabaseTye.Oracle)
    {
        //....
    }    
}

public DbDataReader GetData()
{

    DbCommand comm;
    //...
}

,或者

public bool CreateConnection(DatabaseTypeEnum type)
{
    IDbConnection conn ;

    if(type==DatabaseTye.Oracle)
    {
        //....
    } 
}

public IDbDataReader GetData()
{

    IDbCommand comm;
    //...
}

而且,为什么?

3 个答案:

答案 0 :(得分:5)

嗯......完全不同的问题:)

好的,不...

当你这样做时,你会违反开放式关闭原则......那个特定地方的switch / if语句让我感到不舒服:)。

我将实际创建保留给Factory类,您的代码不应该关心它是否与SQL Server,DB2或Oracle或其他任何内容通信。

理想情况下,您的代码应该只与IDbConnection,IDbCommand等或抽象基类(DbConnection,DbCommand等)通信。有时我确实发现你需要向特定的提供者转发(比如使用特定方法的SqlDataReader),但这种情况很少见。

Factory会将此switch / if语句封装到一个位置,以便于维护。您可以在app.config中进一步抽象实际创建。因此,在app.config中,您可以选择支持哪种类型的数据库后端,工厂将从那里获取并为您创建必要的数据库内容。

请参阅:this。阅读有关创建DbProviderFactory和连接部件的信息......

答案 1 :(得分:0)

为什么不使用泛型?

您可以像这样定义您的类:

public class DBHelper<T, Y, W> where T: DbConnection, new() where Y : DbCommand, new()
{
        private T conn_ = new T();
        private Y comm_ = new Y();            
}

这就是我所做的,而且它很容易维护。

答案 2 :(得分:0)

您应该使用IDbConnectionIDbCommand,因为不同的数据库供应商将有不同的接口实现(对于他们的ADO.NET事物),但更好不完全如此你发布了。您应该将整个类设为通用类,以支持通用IDbConnectionIDbCommand。可能是这样的:

public class Db<T> where T : IDbConnection, new()
{
    public bool CreateConnection()
    {
        T conn;

        //now you dont need these lines since you dont have to worry about
        //what type of db you are using here, since they all implement
        //IDbConnection, and in your case its just T.
        //if(type==DatabaseTye.Oracle)
        //{
            //....
        //}
    }

    public DbDataReader GetData()
    {
        //get comm object from S conn
        using(var conn = new S())
            using (var comm = conn.CreateCommand())

        //...
    }

好处是您可以将要用于DbConnectionDbCommand的类型传递给此类,这对于MySQL .net连接器和Oracle连接器将是不同的。所以你从课外得到某种控制。您可以查看此question and my answer以获取基本实现的参考。