0

我需要构建一个数据访问库,以便以后在许多小型应用程序中使用。

它将大量使用 DataReader 对象。SQL Server 或 DB2/400 中的表可能具有相同的结构。这意味着例如一个方法

GetItemsByWarehouse()

必须能够针对 SQL Server DB 或 DB2 运行。它将在哪里运行取决于服务器可用性和用户选择。

我打算做的(并且需要建议)是:

  1. 实现基于单例设计模式的 DAL,以确保我的库只有一个实例。
  2. 具有将设置连接字符串的属性。
  3. 如果目标服务器是 AS400 或 SQL,则具有将设置的属性。

我不知道这种做法是否正确。我应该实现第 3 点还是可以从连接字符串中获取类型?

另外我应该如何实现上述方法?检查属性并在方法内部决定我是否会使用SqlconnectionOleDbConnection

4

2 回答 2

2

我从我的 micro Orm 粘贴此代码。构造函数有多个重载来指定要使用的 Db。

 public class DbAccess : IDisposable
{
    public DbAccess()
    {
        var cnx=ConfigurationManager.ConnectionStrings[0];
        if (cnx==null) throw new InvalidOperationException("I need a connection!!!");

        Init(cnx.ConnectionString,ProviderFactory.GetProviderByName(cnx.ProviderName));
    }

    public DbAccess(string connectionStringName)
    {
        var cnx = ConfigurationManager.ConnectionStrings[connectionStringName];
        if (cnx == null) throw new InvalidOperationException("I need a connection!!!");

        Init(cnx.ConnectionString, ProviderFactory.GetProviderByName(cnx.ProviderName));
    }

    public DbAccess(string cnxString,string provider)
    {
        Init(cnxString,ProviderFactory.GetProviderByName(provider));
    }

    public DbAccess(string cnxString,DBType provider)
    {
      Init(cnxString,ProviderFactory.GetProvider(provider));
    }

    public DbAccess(string cnxString,IHaveDbProvider provider)
    {
        Init(cnxString, provider);
    } //other stuff
   }

请注意,DAO (DbAccess) 并不关心具体的提供者。这是 ProviderFactory 的外观。在这里,您可以添加一种方法来检测数据库并返回提供程序。

   internal static class ProviderFactory
{
    public static IHaveDbProvider GetProviderByName(string providerName)
    {
        switch (providerName)
        {
            case SqlServerProvider.ProviderName:return new SqlServerProvider();
            case MySqlProvider.ProviderName:return new MySqlProvider();
            case PostgresProvider.ProviderName:return new PostgresProvider();
            case OracleProvider.ProviderName:return new OracleProvider();
            case SqlServerCEProvider.ProviderName:return new SqlServerCEProvider();
            case SqliteProvider.ProviderName:return new SqliteProvider();
        }
        throw new Exception("Unkown provider");
    }

    public static IHaveDbProvider GetProvider(DBType type)
    {
        switch (type)
        {
            case DBType.SqlServer: return new SqlServerProvider();
            case DBType.SqlServerCE: return new SqlServerCEProvider();
            case DBType.MySql: return new MySqlProvider();
            case DBType.PostgreSQL:return new PostgresProvider();
            case DBType.Oracle:return new OracleProvider();
            case DBType.SQLite:return new SqliteProvider();
        }
        throw new Exception("Unkown provider");
    }
}

有关更多代码片段和灵感,您可以查看Github 存储库

我建议不要使用单例模式,让 DI 容器来管理实例生命周期要好得多。此外,应用程序应该使用 DAO 的接口而不是具体实例(这将在未来帮助您)。

于 2012-11-14T12:50:25.433 回答
1

看看抽象工厂模式

您可以拥有一个与 DAL 合同的接口以及每个上下文的实现。使用工厂,它可以决定在每种情况下使用哪个实现。工厂将需要“切换规则”来决定使用什么。

于 2012-11-14T11:17:45.140 回答