我有一个小型图书馆,在其中执行1个长时间运行的操作,并根据该操作在数据库表中保存一些数据。现在这是一个小型图书馆,其中不包含很多数据库表操作,因此我使用了Ado .net来管理数据访问层。
我创建了基类,并在其中放置了连接字符串和Ado.net命令执行。
我有3-4个类,其中某些方法执行插入,更新和删除,但是问题是,每当我创建此类的对象时,我都必须将连接字符串传递给这4个类。
代码:
internal abstract class BaseRepo
{
private readonly string connectionString;
protected int TestId;
protected int VariantId;
public BaseRepo() { }
protected BaseRepo(string connection)
{
this.connectionString = connection;
}
internal virtual void ExecuteQuery(string query,
IList<SqlParameter> parameters)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(query, conn))
{
conn.Open();
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
command.ExecuteNonQuery();
}
}
}
internal virtual void ExecuteQueryWithTransaction(SqlConnection connection,SqlTransaction transaction, string query,
IList<SqlParameter> parameters)
{
using (SqlCommand command = new SqlCommand(query, connection, transaction))
{
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
command.ExecuteNonQuery();
}
}
internal virtual int ExecuteScalar(string query,
IList<SqlParameter> parameters)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(query, conn))
{
conn.Open();
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
var data = command.ExecuteScalar();
if (data == null)
return 0;
return (int)data;
}
}
}
}
internal class VariantRepo : BaseRepo
{
public VariantRepo(string connectionString,int testId,int variantId) : base(connectionString)
{
TestId = testId;
VariantId = variantId;
}
public VariantRepo(testId) : base(connectionString)
{
TestId = testId;
}
public void DeleteVariantData()
{
string query = "";
List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("@TestId", TestId));
parameters.Add(new SqlParameter("@VariantId", VariantId));
ExecuteQuery(query, parameters);
}
}
internal class RegionRepo : BaseRepo
{
public RegionRepo(string connectionString, int variantId) : base(connectionString)
{
VariantId = variantId;
}
public int GetRegionIdByVariantId()
{
string query = "";
List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("@id", VariantId));
return ExecuteScalar(query, parameters);
}
}
如您所见,我这里有4个类,并且必须从每个此类中将连接字符串传递给基类:
1)VariantRepo
2)RegionRepo
3)CategoryRepo
(未显示,但与上面的2相同)
4)TestRepo
(未显示,但与上面的2相同)。
所以我想在这里解决两件事:
1)可以设计基类的方式是,我只需要传递一次连接字符串,而不必传递4个具体类中的每一个?
2)我想将此隐藏在某些类后面的脏逻辑(Sql parameter creation code
)下,以提高可读性,因为我必须在很多地方这样做:
List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("@TestId", TestId));
parameters.Add(new SqlParameter("@VariantId", VariantId));
我认为将基类作为具体类,但比将基类作为抽象类更有意义,我想这就是为什么我将基类标记为抽象。
有人可以帮我设计更好的方法吗?
答案 0 :(得分:0)
这可能不是您要查找的答案,但是我将使用配置文件,将其存储在connstring中,然后在基类中将其设置为静态变量。
答案 1 :(得分:0)
您明确要求的内容是不可能的。每个派生类都必须使用其ctor进行初始化,因此每个ctor必须以一种或另一种方式引入连接字符串。 您可以:
class RepoFactory
{
private readonly string _connectionString;
public RepoFactory(string connectionString)
{
_connectionString = connectionString;
}
public VariantRepo GetVariantRepo(int testId, int variantId) =>
new VariantRepo(_connectionString, testId, variantId);
...
}
ConnectionStringProvider
类或类似的类,该类将具有仅获取属性ConnectionString
(可能从配置文件中读取该值),然后将其注入您的各种存储库。