如何定义处理数据库连接的基类?

时间:2014-03-28 07:39:59

标签: c# database class-design

我有一个带有基类的控制台应用程序,如下所示:

public abstract class PaymentSystemBase : IPayable
{
    private SqlConnection _connection;

    protected PaymentSystemBase()
    {
        CreateDatabaseConnection();
    }

    protected void CreateDatabaseConnection()
    {
        if(_connection == null)
        {
            string connectionString = ConfigurationManager.AppSettings["connString"];
            var connection = new SqlConnection(connectionString);
            _connection = connection;
            connection.Open();
        }
    }

    public SqlConnection Connection
    {
        get { return _connection;  }
    }

    public abstract void ProcessPayment();
}

并且有一些派生自PaymentSystemBase的类:

public class PS1 : PaymentSystemBase
{
    public override void ProcessPayment()
    {
         // Work with database using Connection from PaymentSystemBase
    }
}

public class PS2 : PaymentSystemBase
{
    public override void ProcessPayment()
    {
         // Work with database using Connection from PaymentSystemBase
    }
}

在主程序中:

var lstPayments = new List<IPayable>
{
    new PS1(),
    new PS2()
};

var processPayments = new ProcessPayments(lstPayments);
processPayments.Process();

其中:

public class ProcessPayments
{
    private List<IPayable> _paymentSystems;

    public ProcessPayments(List<IPayable> paymentSystem)
    {
        _paymentSystems = paymentSystem;
    }

    public void Process()
    {
        foreach (var paymentSystem in _paymentSystems)
        {
            paymentSystem.ProcessPayment();
        }
    }
}

我的问题是如何使用PaymentSystemBase类中的相同连接并在处理后关闭它?正如我所看到的,每次创建PS1和PS2时都会再次创建连接。

1 个答案:

答案 0 :(得分:2)

您不应该尝试来共享连接对象。连接对象本身实际上非常轻量级,是在实际物理连接之上构建的抽象,ADO.NET连接池负责创建。

所以你的基类应该是这样的:

public abstract class PaymentSystemBase : IPayable
{
    private static string _connectionString =
        ConfigurationManager.ConnectionStrings["connString"].ConnectionString

    public static string ConnectionString
    {
        get { return _connection;  }
    }

    public abstract void ProcessPayment();
}

然后你的派生类应该是:

public class PS1 : PaymentSystemBase
{
    public override void ProcessPayment()
    {
        using(var conn = new SqlConnection(PaymentSystemBase.ConnectionString))
        {
           using(var cmd = new SqlCommand("...",conn)
           {
               //Prepare command
               conn.Open();
               cmd.ExecuteXXX();
               //Process results, etc
           }
        }
    }
}

您已经注意到我还通过ConfigurationManager类从AppSettingsConnectionStrings切换了加载连接字符串的位置,这是一个专门的部分用于存储连接字符串的配置系统。这实际上并不是必需的,但它更为传统。