数据层抽象工厂

本文关键字:工厂 抽象 数据 | 更新日期: 2023-09-27 17:55:07

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

谢谢

编辑

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);
    }
}

这是我创建的两个类。

数据层抽象工厂

该功能已存在。

将连接字符串添加到 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())
                {
                    // ...
                }
            }
        }
    }
}

许多必需的功能可以从以下位置获得

 System.Data.Common.DbProviderFactories

您可以在其中获取由大多数 dotnet 数据库提供程序实现的System.Data.Common.DbProviderFactory项。

更新

如果你正在寻找工作数据库工厂的例子,请参阅源代码

  • queryexpress一个工作数据库查询GUI,
  • QueryExplus QueryExpress 的一个分支
  • mygeneration是一个代码生成器,可以连接到许多不同的数据库
  • NHibernate与复杂的驱动程序模式,适用于许多数据库

我不会有"createcommand"或"createconnection"方法。

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

连接和命令对象实现 IDisposable。 因此,最好使用使用语句,在其中根据需要创建和处置这些语句。 你现在拥有它的方式可能会导致大量的内存问题。

此外,与在需要创建这些参数的代码中仅调用"new SqlParameter"相比,CreateParameter 方法似乎没有提供任何真正的好处。

我会做以下几点:

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.
        }
    }
  }
}

这样,您的数据层就特定于您提供的功能。 已经有很好的数据库访问包装器,如企业库。 您正在采取的方法不会增加任何内容并引入错误。

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

嗨,

人们,我知道这是旧帖子,但我想与您分享一些东西。

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

创建一个可以调用的项目CustomProvider

创建一个类,您将调用该类数据库

 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. 创建 Seccond 类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;
      }
    }
    

    公共类 SQLDatabase : 数据库 {

      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)
        {
        }
      }
    

必须重写主类中所有定义的方法

  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;
    }