Yah*_*ufi 4 c# sql sql-server winforms
我有一个ac #windows窗体应用程序,动态连接数据库,每个用户可以连接到不同的数据库.
目前的实施情况如下:
连接存储库,包含动态填充的连接列表(每个用户).
当用户发起需要数据库连接的请求时,将从连接存储库中查找相应的连接,打开,然后在用户请求中使用.
连接存储库中的代码示例
public class RepoItem
{
public string databasename;
public SqlConnection sqlcnn;
}
public class ConnectionRepository
{
private List<RepoItem> connectionrepositroylist;
public SqlConnection getConnection(String dbname)
{
SqlConnection cnn = (from n in connectionrepositroylist
where n.databasename == dbname
select n.sqlcnn).Single;
cnn.Open();
return cnn;
}
}
Run Code Online (Sandbox Code Playgroud)
对于任何代码错误,我只是为了演示目的即兴创建了一个小版本的实现.
我没有在命令执行后关闭连接,因为它可能同时被另一个命令使用.
问题是:
我应该担心关闭连接吗?
如果在特定时间段内空闲,连接会自动关闭吗?
我有一个方法是在创建的连接存储库中实现一个计时器,并检查通过它的空闲连接Executing ConnectionState Enumeration并手动关闭它们.欢迎任何建议.
当我想要一个特定的连接时,我调用ConnectionRepository类中的getConnection函数并将数据库名称作为参数传递.
PS:我没有发布完整实现的代码,因为它非常大并且包含影响连接列表填充的首选项.
我建议不要回到SQLConnection调用方法.相反,创建一个接受a的方法,Action<SqlConnection>在using块内创建连接,并在该块内执行操作
这样您就知道连接将始终正确关闭和处理,同时使用代码可以自由地执行所需操作:
public class RepoItem
{
public string databasename;
public SqlConnection sqlcnn;
}
public class DatabaseConnector
{
private List<RepoItem> connectionrepositroylist;
private SqlConnection GetConnection(String dbname)
{
return (from n in connectionrepositroylist
where n.databasename == dbname
select n.sqlcnn).SingleOrDefault();
}
public void Execute(String dbname, Action<SqlConnection> action)
{
using (var cnn = GetConnection(dbname))
{
if (cnn != null) // in case dbname is not in the list...
{
cnn.Open();
action(cnn);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,要执行sql语句,您可以执行以下操作:
public void ExecuteReaderExample(string dbName, string sql)
{
Execute("dbName",
connection =>
{
using (var cmd = new SqlCommand(sql, connection))
{
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// do stuff with data form the database
}
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
当然,你也可以用这样SqlCommand的方法包装.我一直在使用这种方法已经有一段时间了,据我所知,它运作良好.事实上,它运作良好我基于这种方法在git hub上发布了一个项目.
通过以相同的方式包装连接,命令,阅读器和适配器,它在处理ado.net时为您节省了大量的管道.随意下载并适应您的需求.
PS直接回答您的问题:
我应该担心关闭连接吗?
是的你应该.
如果在特定时间段内空闲,连接会自动关闭吗?
不,它没有.
但是,实现像我建议的方法将为您处理关闭和处理连接对象,因此您不必担心它.
正如Yahfoufi在他的评论中写道,这个设计有一个缺陷,因为多个命令使用相同的实例SqlConnection,你在冒着其他命令运行时关闭连接的风险.但是,解决这个设计缺陷是很容易-而不是抱着SqlConnection在RepoItem你可以简单地保持连接字符串:
public class RepoItem
{
public string DatabaseName {get; set;}
public string ConnectionString {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
然后你改变这样的GetConnection方法:
private SqlConnection GetConnection(String dbname)
{
return new SqlConnection(from n in connectionrepositroylist
where n.databasename == dbname
select n.sqlcnn).SingleOrDefault());
}
Run Code Online (Sandbox Code Playgroud)
现在每个Execute方法都在处理它自己的单个实例,SqlConnection因此您不必担心在执行其他命令的过程中关闭.
不过,虽然我们对重构的问题,我建议去掉RepoItem类一起,而不是使用的List<RepoItem>保持连接字符串简单地使用Dictionary<string, string>,其中数据库名称是关键,连接字符串的值.这样,每个数据库名称只能有一个连接字符串,并且您的GetConnection方法简化为:
private Dictionary<string, string> connectionrepositroylist;
private string GetConnectionString(String dbname)
{
return connectionrepositroylist.ContainsKey(dbname) ? connectionrepositroylist[dbname] : "";
}
Run Code Online (Sandbox Code Playgroud)
因此,完整的DatabaseConnector类将如下所示:
public class DatabaseConnector
{
private Dictionary<string, string> connectionrepositroylist;
private string GetConnectionString(String dbname)
{
return connectionrepositroylist.ContainsKey(dbname) ? connectionrepositroylist[dbname] : "";
}
public void Execute(String dbname, Action<SqlConnection> action)
{
var connectionString = GetConnectionString(dbname);
if(!string.IsNullOrEmpty(connectionString))
{
using (var cnn = new SqlConnection(connectionString))
{
cnn.Open();
action(cnn);
}
}
}
// Of course, You will need a way to populate your dictionary -
// I suggest having a couple of methods like this to add, update and remove items.
public bool AddOrUpdateDataBaseName(string dbname, string connectionString)
{
if(connectionrepositroylist.ContainsKey(dbname))
{
connectionrepositroylist[dbname] = connectionString;
}
else
{
connectionrepositroylist.Add(dbname, connectionString);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
803 次 |
| 最近记录: |