Абстрактная Фабрика Уровня Данных
Я новичок в разработке абстрактного фабричного шаблона и хотел бы создать абстрактную фабрику в слое данных, которая поможет мне связать этот слой с любыми другими базами данных, например 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);
}
}
Это два класса, которые я создал..
4 ответов:
Функциональность уже существует.
Добавьте строку подключения к app / webb.конфигурация:
<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();Обновление
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Где вы можете получить элементы
System.Data.Common.DbProviderFactory, которые реализованы большинством dotnet-databaseproviders.Обновление :
Хейвиг ваша собственная фабрика в порядке. если вы ищете примеры рабочих фабрик баз данных, смотрите sourcecode of
- queryexpress рабочий графический интерфейс для запросов к базе данных,
- queryexplus a spinof queryexpress
- mygeneration кодогенератор, который подключается ко многим различным базам данных
- NHibernate со сложной моделью драйвера для многих баз данных
У меня не было бы методов "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. Подход, который вы принимаете, ничего не добавляет и вносит ошибки.
Далее этот подход означает, что вы можете реализовать не-поставщиков баз данных, таких как XML, web услуги и т. д. с нулевыми изменениями кода.
Привет люди, я знаю, что это старый пост, но я хотел бы поделиться кое-чем с вами.
Библиотека Enterprise и 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(); } }
- Создать Класс Seccond
OracleDatabase.csСоздать третий класс
SQLDatabase.cspublic 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; } }И далее по программе
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) { } }Вы должны переопределить все определенные методы в мастер-классе
Создать
Factory.cspublic 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; }
Comments