我是C#和使用Windows窗体的新手。
我正在构建一个项目,其中包含约25Forms和25user controls以及其中的每一个,Forms并且user controls使用SQL数据库从数据库中读取数据(请注意,我在app.config文件内部使用连接字符串)。
Forms
user controls
app.config
如代码中所示,我总是将sql查询放入50个Form /用户控件构造函数中,以从数据库中读取数据(例如控件文本和其他内容)。
我的程序运行正常,没有问题,但是想象一下,当我运行程序25forms和25时,它们user controls都将“同时”查询数据库,这使我感到自己做错了,以后可能会对程序产生副作用。
forms
我不知道这是将查询放入构造函数内的正确方法(例如按钮文本查询)吗?我也觉得25Forms和25user controls在运行时会同时攻击SQL数据库,因此有没有办法减少与数据库的连接数?请指导我。谢谢
public partial class SubMenu1 : UserControl { SqlConnection MyConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString); SqlCommand MyCommand = new SqlCommand(); DataTable DataTable = new DataTable(); SqlDataAdapter Sql_Data_Adapter = new SqlDataAdapter(); public SubMenu1() { InitializeComponent(); DataTable.Rows.Clear(); DataTable.Columns.Clear(); MyConnection.Open(); MyCommand.CommandText = "SELECT * FROM Table21 "; MyCommand.Connection = MyConnection; Sql_Data_Adapter.SelectCommand = MyCommand; Sql_Data_Adapter.Fill(DataTable); MyConnection.Close(); } public void MyFunction() { // Do some stuff with the DataTable ... } }
您的代码有很多问题。首先不要使用全局连接,这里有Connection Pool。
连接池减少了必须打开新连接的次数。池管理者维护物理连接的所有权。它通过为每个给定的连接配置保留一组活动的连接来管理连接。每当用户在连接上调用“打开”时,池管理器就会在池中寻找可用的连接。如果池化连接可用,它将把它返回给调用者,而不是打开一个新连接。当应用程序在连接上调用“关闭”时,池化程序将其返回到活动连接的池化集中,而不是将其关闭。一旦将连接返回到池中,就可以在下一个Open调用中重用该连接。
您也应该在使用中或在try / catch / finally块中使用连接。这是必需的,因为如果发生某些异常,连接将永远不会中断,Closed并且在您尝试重用它时将导致异常,或者它将永远不会返回到连接池。
Closed
再次将SqlDataAdapter包装在using块中,您需要在完成使用后关闭适配器。您需要调用Dispose,因此SqlAdapter释放该组件使用的所有资源。这是每个IDisposable对象的规则。如果不进行处置,则处置将在GC终结器上进行,但是何时执行由GC决定。因此,不处理此对象会产生高昂的成本。这是msdn中有关IDisposable的文章
Dispose
IDisposable
我建议您创建一个单独的数据访问层,在这个问题中我简单地说明了设计问题:检查用户名或用户电子邮件是否已存在
如果您不想使用单独的数据访问层,则代码应如下所示:
public partial class SubMenu1 : UserControl { public SubMenu1() { InitializeComponent(); } public void MyFunction() { DataTable dataTable = new DataTable(); using(SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString)) using(SqlDataAdapter sqlDataAdapter = new SqlDataAdapter()) { myConnection.Open(); SqlCommand myCommand = new SqlCommand(); myCommand.CommandText = "SELECT * FROM Table21"; myCommand.Connection = myConnection; sqlDataAdapter.SelectCommand = myCommand; sqlDataAdapter.Fill(dataTable); } if(dataTable.Rows.Count > 0) { //do stuff .... } } }