2014-03-28 35 views
0

我有一个基类控制台应用程序如下:如何定义处理数据库连接的基类?

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时都会再次创建连接。

+0

使用try catch和finally块来实现实际的数据库操作,然后在父类中定义一个连接关闭方法,并最终在子类中调用它,以便确保数据库操作完成时,连接是关闭的,按照当前的代码,最好在PS1和PS2完成后在Main函数内调用close方法 –

+2

我可以猜测这是c#,但我不应该这么做。请编辑您的问题并添加合适的语言标记。但如果这是.NET,那么我会说,请停止尝试这样做。你不应该*尝试*共享周围的连接对象。您应该在需要使用它之前立即创建并打开连接,然后立即关闭/处理它。连接池负责限制使用的实际物理连接的数量。 –

+0

@ Damien_The_Unbeliever:是的,这是C#代码。我已经在原文中添加了这些信息。你的意思是我应该在每次使用PS1,PS2等对象时打开和关闭数据库连接? – tesicg

回答

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类从AppSettings加载到ConnectionStrings,这是用于存储连接字符串的配置系统的专用部分。这实际上并不需要,但它更传统。

相关问题