在C#/ ADO.NET中抽象出DB服务器类型

时间:2016-03-29 15:55:38

标签: c# design-patterns ado.net

C#/ ADO.NET有:

SqlConnection / NpgsqlConnection / ...
SqlCommand / NpgsqlCommand / ...
SqlDataReader / NpgsqlDataReader / ...
...

这意味着您的所有数据库代码最终都是特定于数据库供应商的。如果更改数据库供应商,则必须更改所有数据库调用。并且,您无法使您的代码数据库供应商不可知。

我不介意创建数据库供应商特定的连接,但从那时起,我希望我的所有数据库调用都是通用的,例如Command和DataReader。

我知道我可以通过创建Command和DataReader等类来实现这一点,这些类可以包含调用适当的供应商特定调用的switch语句,但我更喜欢做一些更优雅的事情。我觉得标准设计模式之一可能有所帮助,但我还没有找到一个优雅的解决方案。任何帮助肯定会受到赞赏。

2 个答案:

答案 0 :(得分:0)

  

这意味着您的所有数据库代码最终都是特定于数据库供应商的。   如果更改数据库供应商,则必须更改所有数据库调用。   并且,您无法使您的代码数据库供应商不可知。

是。除非您阅读文档并意识到它们都实现了通用接口。所需要的只是一个易于更换的小工厂方法。

然后问题开始了。 SQL方言非常不同,参数的附加方式是(不是C#部分 - 但它们必须在SQL代码中如何命名和引用。

易于标准化的程序化界面非常简单。

除了完整的驱动程序模型之外,没有办法概括SQL级别,即具有抽象(如LINQ),然后从那里使用特定的生成器。

答案 1 :(得分:-1)

    abstract class AbstractFactory  {
        public abstract System.Data.Common.DbConnection CreateConnection(string cs);
        public abstract System.Data.Common.DbCommand  CreateCommand(string stmt, System.Data.Common.DbConnection conn);
    }

    class ConcreteFactorySql : AbstractFactory {
        public override System.Data.Common.DbConnection CreateConnection(string cs) {
            return new SqlConnection(cs);
        }
        public override System.Data.Common.DbCommand CreateCommand(string stmt, System.Data.Common.DbConnection conn) {
            return new SqlCommand(stmt, (SqlConnection) conn);
        }
    }

    class ConcreteFactoryPg : AbstractFactory {
        public override System.Data.Common.DbConnection CreateConnection(string cs) {
            return new NpgsqlConnection(cs);
        }
        public override System.Data.Common.DbCommand CreateCommand(string stmt, System.Data.Common.DbConnection conn) {
            return new NpgsqlCommand(stmt, (NpgsqlConnection) conn);
        }
    }