Как правильно организовать класс по работе с БД - C#
Формулировка задачи:
Здравствуйте. У меня есть проект каталогизатора. Изначально писал основываясь на MSSQL CE. Потом захотел добавить возможность использования MSSQL Server. И начал сочинять))
Написал фабрику возвращающую класс по работе с конкретной СУБД
где DBType - перечисление с вариантами СУБД
Написал абстрактный класс по работе с СУБД где перечислил абстрактные классы по работе с таблицами в БД
От него унаследовал класс работы с конкретной СУБД.
Написал набор абстрактных классов по работе с таблицами (на примере ProjectTable)
Написал набор конкретных классов по работе с таблицами (на примере ProjectTable)
Мне бы хотелось вынести метод SQLExec из каждого конкретного класса вынсти в некий класс (возможно абстактный)?
Посмотрев диаграмму классов на все это "творчества", у меня возник вопрос, а не должены ли абстрактные классы наледоваться от какого-то общего класса куда можно было бы вынести общие методы как, например SQLExec?
Прошу дать оценку моему певому опыту работы с фабрикой.
public static class DbProviderFactory
{
public static DatabaseProvider GetProvider(DBType dbType, string ConnectStr)
{
DatabaseProvider provider = null;
switch (dbType)
{
case DBType.MSSQL:
provider = new SqlDbProvider(ConnectStr);
break;
case DBType.MSSQLCE:
provider = new SqlCeDbProvider(ConnectStr);
break;
default:
throw new ArgumentException("Wrong database type!");
}
return provider;
}
}public enum DBType
{
None,
MSSQL,
MSSQLCE
}public abstract class DatabaseProvider
{
protected string CONNECT_STR = string.Empty;
protected IDbConnection CNN = null;
public DatabaseProvider(string connectStr)
{
CONNECT_STR = connectStr;
}
public abstract ProjectTableAbstract GetProjectTable();
public abstract FirstUsageTableAbstract GetFirstUsageTable();
public abstract OboznachenieTableAbstract GetOboznachenieTable();
public abstract LiteralTableAbstract GetLiteralTable();
public abstract IspolniteliTableAbstract GetIspolniteliTable();
public abstract InventarNumberTableAbstract GetInventarNumberTable();
}public class SqlCeDbProvider : DatabaseProvider // Для MSSQL CE
{
public SqlCeDbProvider(string connectStr)
: base(connectStr)
{
CNN = new SqlCeConnection(CONNECT_STR);
}
public override ProjectTableAbstract GetProjectTable()
{
return new ProjectTableSqlCe(CNN);
}
public override FirstUsageTableAbstract GetFirstUsageTable()
{
return new FirstUsageTableSqlCe(CNN);
}
public override OboznachenieTableAbstract GetOboznachenieTable()
{
return new OboznachenieTableSqlCe(CNN);
}
public override LiteralTableAbstract GetLiteralTable()
{
return new LiteralTableSqlCe(CNN);
}
public override IspolniteliTableAbstract GetIspolniteliTable()
{
return new IspolniteliTableSqlCe(CNN);
}
public override InventarNumberTableAbstract GetInventarNumberTable()
{
return new InventarNumberTableSqlCe(CNN);
}
}
class SqlDbProvider : DatabaseProvider // Для MSSQL Server
{
public SqlDbProvider(string connectStr)
: base(connectStr)
{
CNN = new SqlConnection(CONNECT_STR);
}
public override OboznachenieTableAbstract GetOboznachenieTable()
{
throw new NotImplementedException();
}
public override FirstUsageTableAbstract GetFirstUsageTable()
{
throw new NotImplementedException();
}
public override ProjectTableAbstract GetProjectTable()
{
throw new NotImplementedException();
}
public override LiteralTableAbstract GetLiteralTable()
{
throw new NotImplementedException();
}
public override IspolniteliTableAbstract GetIspolniteliTable()
{
throw new NotImplementedException();
}
public override InventarNumberTableAbstract GetInventarNumberTable()
{
throw new NotImplementedException();
}
}public abstract class ProjectTableAbstract
{
protected IDbConnection CNN = null;
public ProjectTableAbstract(IDbConnection Connection)
{
CNN = Connection;
}
public abstract List<Project> GetEntities();
public abstract bool AddToDB(string value);
public abstract bool DeleteFromDB(string value, int id);
public abstract bool RenameInDB(string oldValue, string newValue, int oldValueId);
}class ProjectTableSqlCe : ProjectTableAbstract
{
static SqlCeConnection SQLCeCon;
public ProjectTableSqlCe(IDbConnection Connection) : base(Connection)
{
SQLCeCon = (SqlCeConnection)CNN;
}
public override List<Project> GetEntities()
{
List<Project> _lst = new List<Project>();
if (SQLCeCon.State == ConnectionState.Closed)
{
SQLCeCon.Open();
}
_lst.Clear();
SqlCeCommand ceCmd;
SqlCeDataReader ceDR;
ceCmd = new SqlCeCommand("", (SqlCeConnection)CNN);
ceDR = ceCmd.ExecuteReader();
while (ceDR.Read())
{
_lst.Add(new Project((int)ceDR[0], (string)ceDR[1]));
}
ceDR.Close();
CNN.Close();
return _lst;
}
public override bool AddToDB(string value)
{
int i = -1;
string cmd = "";
SqlCeCommand _cmd = new SqlCeCommand();
_cmd = new SqlCeCommand(cmd, SQLCeCon);
_cmd.Parameters.Add("@prj_name", SqlDbType.NVarChar).Value = value;
i = SQLExec(_cmd);
GetEntities();
return i > 0;
}
public override bool DeleteFromDB(string value, int id)
{
string cmd = "";
int i = -1;
SqlCeCommand _cmd = new SqlCeCommand();
_cmd = new SqlCeCommand(cmd, SQLCeCon);
_cmd.Parameters.Add("@id", SqlDbType.Int).Value = id;
try
{
i = SQLExec(_cmd);
}
catch (Exception ex)
{
if (ex is SqlCeException)
{
ExceptionHandler.SQLEntityException exc =
new ExceptionHandler.SQLEntityException();
throw exc;
}
else
{ throw ex; }
}
return i > 0;
}
public override bool RenameInDB(string oldValue, string newValue, int oldValueId)
{
string cmd = "";
int i = -1;
SqlCeCommand _cmd = new SqlCeCommand();
_cmd = new SqlCeCommand(cmd, SQLCeCon);
_cmd.Parameters.Add("@id", SqlDbType.Int).Value = oldValueId;
_cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = newValue;
try
{
i = SQLExec(_cmd);
}
catch (Exception ex)
{
if (ex is SqlCeException)
{
ExceptionHandler.SQLEntityException exc =
new ExceptionHandler.SQLEntityException();
throw exc;
}
else
{ throw ex; }
}
GetEntities();
return i > 0;
}
protected int SQLExec(SqlCeCommand SQLCommand)
{
int i = -1;
if (CNN.State == ConnectionState.Closed)
{
CNN.Open();
}
try
{
i = SQLCommand.ExecuteNonQuery();
}
finally
{
CNN.Close();
}
return i;
}
}Решение задачи: «Как правильно организовать класс по работе с БД»
textual
Листинг программы
public abstract class ProjectTableAbstract
{
private readonly string _connectionString;
protected ProjectTableAbstract(string connectionString)
{
_connectionString = connectionString;
}
public virtual List<Project> GetEntities()
{
return Query<List<Project>>("Your query");
}
public virtual bool AddToDb(string value)
{
return SqlExecuteNonQuery("Your query") > -1;
}
public virtual bool DeleteFromDb(string value, int id)
{
return SqlExecuteNonQuery("Your query") > -1;
}
public virtual bool RenameInDb(string oldValue, string newValue, int oldValueId)
{
return SqlExecuteNonQuery("Your query") > -1;
}
protected abstract IDbConnection GetConnection(string str);
protected abstract IDbCommand GetCommand(IDbConnection connection, string query);
protected virtual int SqlExecuteNonQuery(string query)
{
using (var connection = GetConnection(_connectionString))
{
connection.Open();
using (var command = GetCommand(connection,query))
{
return command.ExecuteNonQuery();
}
}
}
protected virtual T Query<T>(string query)
{
using (var connection = GetConnection(_connectionString))
{
connection.Open();
using (var command = GetCommand(connection, query))
{
//парсинг результата запроса и запись в модель
return default(T);
}
}
}
}
public class ProjectTableSqlCe : ProjectTableAbstract
{
public ProjectTableSqlCe(string connectionString) : base(connectionString)
{
}
protected override IDbConnection GetConnection(string str)
{
throw new NotImplementedException();
}
protected override IDbCommand GetCommand(IDbConnection connection, string query)
{
throw new NotImplementedException();
}
}
public class ProjectTableMsSql:ProjectTableAbstract
{
public ProjectTableMsSql(string connectionString) : base(connectionString)
{
}
protected override IDbConnection GetConnection(string str)
{
throw new NotImplementedException();
}
protected override IDbCommand GetCommand(IDbConnection connection, string query)
{
throw new NotImplementedException();
}
}
public static class TableFactory
{
public static ProjectTableAbstract GetTable(string name,string connectionString)
{
throw new NotImplementedException();
}
}