如何为所有数据库操作设计面向对象的C#类,如执行查询,执行SP,执行标量查询等?

时间:2014-04-10 14:24:40

标签: c# sql oop

具有执行查询,执行存储过程,执行标量查询的方法的类,基本上是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();
        }
    }
 }}

1 个答案:

答案 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。现在,抽象这个很多更容易。现在我们只需构建一个处理QueryExecute的接口,这两种方法将与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();

因为它会根据配置获取正确的具体内容。