具有执行查询,执行存储过程,执行标量查询的方法的类,基本上是Oracle和Microsoft数据库的所有数据库操作。目前我有一个类,每个操作有不同的方法,但有很多重复代码。如何以适当的面向对象的方式设计它?
这是我目前所拥有的:我有类似的方法,比如execute for execute scalar,返回一个字符串,执行返回int的标量等等。
public class DBoperations
{
private string querystringval;
private string logfileloc;
private string connectionstringval;
LogToFile logobj = new LogToFile();
SqlConnection SqlConn = new SqlConnection();
public string logfilelocval
{
get { return logfileloc; }
set { logfileloc = value; }
}
public string queryValue
{
get { return querystringval; }
set { querystringval = value; }
}
public string connectionvalue
{
get { return connectionstringval; }
set { connectionstringval = value; }
}
public Boolean connecttodb()
{
logobj.fileName = logfilelocval;
//SqlConnection SqlConn = new SqlConnection(connectionvalue);
SqlConn.ConnectionString = connectionvalue;
try
{
SqlConn.Open();
logobj.MyLogFile("**SUCCESS** ", "Database connection opened");
return true;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
logobj.MyLogFile("**FAILURE**", "Database Connection Failed" + e.Message);
return false;
throw new IndexOutOfRangeException();
}
}
public string executeaquery()
{
try
{
SqlCommand querystring = new SqlCommand(queryValue, SqlConn);
querystring.CommandTimeout = 90;
querystring.ExecuteNonQuery();
logobj.MyLogFile("**SUCCESS** ", "Query Executed Successfully.");
querystring.Dispose();
return "True";
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
logobj.MyLogFile("**FAILURE**", "Query did not execute." + e.Message);
return e.Message;
throw new IndexOutOfRangeException();
}
}
}}
答案 0 :(得分:4)
所以看起来你只是想抽象出实现,以便你可以连接到不同的数据库引擎。这可以通过Dapper之类的方式更好地完成,因为它只是扩展 IDbConnection
接口。这意味着可以使用任何具有实现IDbConnection
的连接对象的数据库引擎;顺便说一下,这就是全部。 :d
好吧,所以对于Dapper你可能会做这样的事情:
using (SqlConnection c = new SqlConnection(connString))
{
var customer = c.Query<Customer>(
"SELECT FirstName, LastName, DateOfBirth FROM Customer WHERE CustomerID = @CustomerID",
new { CustomerID = 1 });
}
那将 你Customer
。现在,抽象这个很多更容易。现在我们只需构建一个处理Query
和Execute
的接口,这两种方法将与Dapper一起使用:
public interface IMyConnection
{
TModel Query<TModel>(string sql, object parms);
int Execute(string sql, object parms);
}
现在我们有了一个接口,我们可以像这样构建该接口的不同具体版本:
public class MsSqlMyConnection : IMyConnection
{
public TModel Query<TModel>(string sql, object parms)
{
using (SqlConnection c = new SqlConnection(connString))
{
return c.Query<TModel>(sql, parms);
}
}
public int Execute(string sql, object parms)
{
using (SqlConnection c = new SqlConnection(connString))
{
return c.Execute(sql, parms);
}
}
}
好的,现在我们有一个具体的,但可以使用任何类型的IDbConnection
,如OracleConnection
。现在我们已经拥有了,而不是构建连接,我们构建我们的连接之一:
var c = new MsSqlMyConnection();
var customer = c.Query<Customer>(
"SELECT FirstName, LastName, DateOfBirth FROM Customer WHERE CustomerID = @CustomerID",
new { CustomerID = 1 });
Dapper构建的许多其他方法可以同时返回类型集合甚至多种类型。您只需要扩展您的界面以支持您的需求,就是这样。然后,您可以使用依赖项注入容器在执行期间实例化正确的具体类。研究StructureMap或Unity等容器的使用。
DI容器将替换此行:
var c = new MsSqlMyConnection();
因为它会根据配置获取正确的具体内容。