数据层抽象工厂

时间:2011-05-05 13:43:57

标签: c# asp.net factory-pattern

我是开发抽象工厂模式的新手,并希望在数据层中创建一个抽象工厂,它将帮助我将此层链接到任何其他数据库,例如sql和oracle。你能帮我完成这项任务吗?请注意,数据库的连接字符串将在此层中找到,而不是在演示文稿中。

由于

EDITED

public abstract class Database
{
    public string connectionString;

    #region Abstract Functions

    public abstract IDbConnection CreateConnection();
    public abstract IDbCommand CreateCommand();
    public abstract IDbConnection CreateOpenConnection();
    public abstract IDbCommand CreateCommand(string commandText, IDbConnection connection);
    public abstract IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection);
    public abstract IDataParameter CreateParameter(string parameterName, object parameterValue);

    #endregion
}

public class SQLDatabase : Database
{
    public override IDbConnection CreateConnection()
    {
        return new SqlConnection(connectionString);
    }

    public override IDbCommand CreateCommand()
    {
        return new SqlCommand();
    }

    public override IDbConnection CreateOpenConnection()
    {
        SqlConnection connection = (SqlConnection)CreateConnection();
        connection.Open();

        return connection;
    }

    public override IDbCommand CreateCommand(string commandText, IDbConnection connection)
    {
        SqlCommand command = (SqlCommand)CreateCommand();

        command.CommandText = commandText;
        command.Connection = (SqlConnection)connection;
        command.CommandType = CommandType.Text;

        return command;
    }

    public override IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection)
    {
        SqlCommand command = (SqlCommand)CreateCommand();

        command.CommandText = procName;
        command.Connection = (SqlConnection)connection;
        command.CommandType = CommandType.StoredProcedure;

        return command;
    }

    public override IDataParameter CreateParameter(string parameterName, object parameterValue)
    {
        return new SqlParameter(parameterName, parameterValue);
    }
}

这是我创建的两个课程。

4 个答案:

答案 0 :(得分:8)

功能已存在。

将连接字符串添加到app / webb.config:

<connectionStrings>
    <add name="TheDatabase" providerName="System.Data.OleDb" connectionString="Provider=OraOLEDB.Oracle.1;Persist Security Info=False;User Id=xxx;Password=yyy;Data Source=zzzz;Extended Properties="/>
  </connectionStrings>

使用工厂建立连接:

var connectionString = ConfigurationManager.ConnectionStrings["TheDatabase"];
var providerName = connectionString.ProviderName;
var factory = DbProviderFactories.GetFactory(providerName);

获取连接:

var connection = factory.CreateConnection();

获取命令:

var command == connection.CreateCommand();

您唯一需要做的就是在app / web.config中切换驱动程序。不需要进行其他更改。

更新

public class Database
{
    public static IDbConnection CreateOpenConnection()
    {
        var connectionString = ConfigurationManager.ConnectionStrings["TheDatabase"];
        var providerName = connectionString.ProviderName;
        var factory = DbProviderFactories.GetFactory(providerName);
        var connection = factory.CreateConnection();
        connection.Open();
        return connection;
    }
}

class FlowerManager : DataWorker
{
    public static void GetFlowers()
    {
        using (IDbConnection connection = Database.CreateOpenConnection())
        {
            using (IDbCommand command = connection.CreateCommand("SELECT * FROM FLOWERS", connection))
            {
                using (IDataReader reader = command.ExecuteReader())
                {
                    // ...
                }
            }
        }
    }
}

答案 1 :(得分:4)

可以从

获得许多所需的功能
 System.Data.Common.DbProviderFactories

您可以获取大多数dotnet-databaseproviders实现的System.Data.Common.DbProviderFactory项。

<强>更新

havig你自己的工厂很好。如果您想了解工作数据库工厂的示例,请参阅

源代码

答案 2 :(得分:0)

我没有“createcommand”或“createconnection”方法。

更好的方法是让每个访问方法(如“GetAccounts”)处理自己的连接/命令实例化。

Connection和Command对象实现IDisposable。因此,最好使用using语句来创建和处理这些语句。你现在拥有它可能会导致大量内存问题。

此外,CreateParameter方法似乎没有提供任何真正的好处,而只是在需要创建这些参数的代码中调用“new SqlParameter”。

我会做以下事情:

public interface IDbAccess {
  String ConnectionString;

  Collection<Account> GetAccountsById(Int32 id);
  Boolean StoreAccount(Account acct);
}

public class SqlDatabase : IDbAccess {
  public String ConnectionString {get; set;}

  public SqlDatabase(String connection) {
    ConnectionString = connection;
  }

  public Collection<Account> GetAccountsById(Int32 id) {
    using (SqlConnection connect = new SqlConnection(ConnectionString)) { 
       using (SqlCommand cmd = new SqlCommand(connect)) {
          /// etc.
        }
    }
  }
}

这样,您的数据层特定于您提供的功能。像Enterprise Library这样的db访问已有很好的包装器。你采取的方法不会增加任何内容并引入错误。

此外,这种方法意味着您可以实现非数据库提供程序,如XML,Web服务等,无需更改代码。

答案 3 :(得分:0)

嗨,大家好我知道这是老帖子,但我想和你分享一些东西。

企业库和OleDb有一些问题,当你想要插入大于32k的图像时,它会抛出异常,所以我已经完成了解决这个问题:

创建一个项目,您可以调用CustomProvider

创建一个Classe,您将其称为数据库

 public abstract class Database
 {
    public string ConnectionString { get; set; } // Preciso uma variavel para guardar o ConnectionString
    public IDbConnection Connection { get; set; }


    //public abstract string ProviderName { get; } // Preciso uma variavel para guardar o ConnectionString


    //public abstract IDbConnection CreateConnection(string ConnectionString);

    public abstract IDbConnection CreateConnection(); // Preciso um Metodo Abstract para CreateConnection Para Tratar da Connection
    public abstract IDbCommand CreateCommand();

    }
}
  1. 创建第二级OracleDatabase.cs
  2. 创建第三课SQLDatabase.cs

     public class OracleDatabase : Database
     {
    
      public override IDbConnection CreateConnection()
      {
          return new OracleConnection(ConnectionString);
      }
    
      public override IDbCommand CreateCommand()
      {
          return new OracleCommand();
      }
    
      public override IDbConnection CreateOpenConnection()
      {
          OracleConnection connection = (OracleConnection)CreateConnection();
          connection.Open();
    
          return connection;
      }
    
      public override IDbCommand CreateCommand(string commandText, IDbConnection connection)
      {
          OracleCommand command = (OracleCommand)CreateCommand();
    
          command.CommandText = commandText;
          command.Connection = (OracleConnection)connection;
          command.CommandType = CommandType.Text;
    
          return command;
      }
    }
    

    public class SQLDatabase:Database    {

      public override IDbConnection CreateConnection()
      {
          return new SqlConnection(ConnectionString);
      }
    
      public override IDbCommand CreateCommand()
      {
          return new SqlCommand();
      }
    
      public override IDbConnection CreateOpenConnection()
      {
          SqlConnection connection = (SqlConnection)CreateConnection();
          connection.Open();
    
          return connection;
      }
    
      public override IDbCommand CreateCommand(string commandText, IDbConnection connection)
      {
          SqlCommand command = (SqlCommand)CreateCommand();
    
          command.CommandText = commandText;
          command.Connection = (SqlConnection)connection;
          command.CommandType = CommandType.Text;
    
          return command;
      }
    
      public override IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection)
      {
          SqlCommand command = (SqlCommand)CreateCommand();
    
          command.CommandText = procName;
          command.Connection = (SqlConnection)connection;
          command.CommandType = CommandType.StoredProcedure;
    
          return command;
        }
     }
    
  3. 然后是程序

        Database db = Factory.CreateDatabase("ConnectionString");
    
        try
        {
            using (IDbConnection w_connection = db.Connection)
            {
                w_connection.Open();
    
                IDbTransaction transation = w_connection.BeginTransaction();
    
                IDbCommand dbcomand = db.CreateStoredProcCommand("INSERTTEST");
    
                db.AddInParameter(dbcomand, "@ATTCH", DbType.Binary, bytes);
                db.ExecuteNonQuery(dbcomand, transation);
    
                transation.Commit();
            }
        }
        catch (Exception)
        {
    
        }
      }
    
  4. 您必须覆盖主类中所有已定义的方法

    1. 创建 Factory.cs

      public static Database CreateDatabase(string ConnectionString)
      {
          //var Conn = ConfigurationManager.ConnectionStrings[ConnectionString].ToString();
      
      
          if (string.IsNullOrEmpty(ConnectionString))
              throw new Exception("Connectionstring Not Found" + ConnectionString);
      
          Database db = null;
      
          if (ConfigurationManager.ConnectionStrings[ConnectionString].ProviderName.Contains("Oracle"))
          {
              db = new OracleDatabase();
              db.ConnectionString = GetConnectionString(ConnectionString);
              db.Connection = db.CreateConnection();
          }
          else
          {
              db = new SQLDatabase();
              db.ConnectionString = GetConnectionString(ConnectionString);
              db.Connection = db.CreateConnection();
          }
      
      
          return db;
      }