数据访问层设计:不同的提供者相同的表和单例

时间:2012-11-14 11:09:49

标签: c# database design-patterns data-access-layer

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

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

GetItemsByWarehouse()

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

我打算做什么(并需要建议):

  1. 基于Singleton设计模式实现DAL,以确保我只有一个库实例。
  2. 拥有一个将设置连接字符串的属性。
  3. 如果目标服务器是AS400或SQL,则设置一个属性。
  4. 我不知道这一行动是否正确。我应该实现点#3还是我可以从连接字符串中获取类型?

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

2 个答案:

答案 0 :(得分:2)

我从我的微观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 repo

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

答案 1 :(得分:1)

查看Abstract Factory Pattern

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