最佳方法制作中央SqlConnection

5

我一直在思考如何最好地建立一个 central SqlConnection(中央的SqlConnection连接)。所以当我开始使用C#进行编程时,我首先把 SqlConnection 放在我制作的每个表单中,就像这样:

public partial class form1 : Form
{
    SqlConnection conn = new SqlConnection(
"Data Source=SERVER\\SQL;Initial Catalog=DataBase;User ID=user;Password=pass");

    public form1 ()
    {
        InitializeComponent();
        timer1.Start();
    }
   }

现在我想建立一个“中央”连接,摆脱每个表单开头的所有代码。我认为使用类会是最好的方法。所以我想问你是否有另一种好的方法来实现这一点。由于我是初学者,请原谅我的描述水平。感谢您的答复/评论/意见。

最佳实践通常是将连接字符串放在 .config 文件中。然后在构造函数中引用该字符串。 - Geeky Guy
@Renan 感谢您的评论,这种做法是否还有可能连接变量?基本上我想从文本框中读取 SqlConnection 的信息(如用户、初始目录、密码)。 - Blaze M
您可以在文件中拥有多个命名的连接字符串。然后,在代码中使用一些逻辑来选择最合适的连接字符串。因此,是的,您可以变化使用的字符串。 - Geeky Guy
5个回答

3

存储SqlConnection信息的标准方法是使用配置文件,比如app.config或web.config。也可以创建您自己的配置文件。

之后,使用ConfigurationManager.ConnectionStrings["YourConnectionStringName"].ConnectionString而不是硬编码的连接设置。


2
使用一个“中心”连接是不被推荐的,因为它会破坏ADO.NET实现的多个模式。相比之下,使用“中心连接字符串”会更容易。如果您想要使用动态参数,可以考虑使用“SqlConnectionStringBuilder”类。
ADO.NET围绕着“晚获取,早释放”的数据库连接模式构建。其他尝试迟早会导致巨大的问题(相信我,我见过很多次:网络错误/事务错误/并发错误/多线程错误...)
ADO.NET使用“连接池”来管理实际物理连接到数据库。因此,除非您为每个连接使用不同的连接字符串,否则您应该最终只有一个连接。但由于“池”管理了这一个连接,所以当它被(重新)打开时,它总是处于一个干净的状态。
个人而言,我喜欢使用这样的连接字符串:
internal static class DataSource
{
    private static string _ConnectionString;
    public static string ConnectionString
    {
        get
        {
            if (_ConnectionString == null)
                _ConnectionString = FunctionToDynamicallyCreateConnectionstring();
            return _ConnectionString;
        }
    }
    private static string FunctionToDynamicallyCreateConnectionstring()
    {
         SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder();
         // initialize cb's properties here...
         return cb.ToString();
    }
}

以及之后

SqlConnection connection = new SqlConnection(DataSource.ConnectionString);

这个模式将确保我的代码中使用完全相同的连接字符串,并且动态代码仍然只运行一次。
[编辑]在大多数情况下,我避免将整个连接字符串编码到app.config文件中,因为某些参数可能对我的代码起着强制作用,不应该被更改。我为“服务器”或“数据库”属性创建自定义设置,读取并分配给ConnectionStringBuilder...

您好,很抱歉晚联系您。将连接的密码和ID保存在txt文件中并从中读取是安全的吗? - Marek
“安全”是指“安全”还是“稳定”?答案分别是否和是。我会尽可能使用“集成安全性”,即传递“当前用户”。这样,应用程序就不需要存储任何凭据,用户或操作系统(在服务或计划任务的情况下)有责任保护任何凭据的安全。任何添加到凭据中的加密(无论是在连接字符串配置还是txt文件中)都会遭受“应用程序必须具有密钥,因此易受攻击”的综合症的影响。 - Roman Gruber

1
不要使用单一的全局连接,因为如果连接断开(由于网络错误),您的应用程序将停止工作。此外,您可能会发现有事务意外留在打开状态或设置其他部分代码未预期的选项的bug。
相反,全球存储连接字符串并每次需要时创建一个新的连接。最好每次从头开始。
static class ConnectionFactory
{
 public static SqlConnection Create() {
  return new SqlConnection(GetConnectionStringSomehow());
 }
}

像这样使用它:

using (var conn = ConnectionFactory.Create()) {
 //do something
}

谢谢您的回答,那么有没有办法从另一个窗体中“创建现有”SqlConnection呢? - Blaze M
不确定“创建现有连接”是什么意思...您可以从任何地方调用ConnectionFactory.Create,包括从其他窗体中。请参阅更新的代码示例。 - usr

0
如果您只想要一个全局可访问的 SQL 连接对象,那么可以考虑使用静态类,因为您可以创建带有静态构造函数的静态类,以便所有内容都可以访问它。
但是我不会这样做,但如果您正在学习,那么也没有什么伤害,但静态/单例通常用于在整个应用程序中拥有一个组件实例。
// Simple static example
public static class DatabaseConnection
{
    public static IDBConnection ActiveConnection {get; private set;}

    static DatabaseConnection()
    {
        var myConnectionString = // get your connection string;
        ActiveConnection = new SqlConnection(myConnectionString);
        ActiveConnection.Connect(); // This is bad, really should be in a using
    }
}

// Simple static usage
DatabaseConnection.ActiveConnection.ExecuteQuery(blah);

问题在于你无法控制该资源,它也不会在应用程序关闭之前关闭连接,这是一种不好的做法。因此,你可以稍微改进一下,同时仍然保持全局可访问的功能。
// Better static example using actions
public static class DatabaseConnection
{
    private static string connectionString;

    public static void OpenConnectionAnd(Action<Connection> actionToDo)
    {
        using(var connection = new SqlConnection(this.connectionString))
        {
            connection.Connect();
            actionToDo.Invoke(connection);
            connection.Disconnect();
        }       
    }

    static DatabaseConnection()
    {
        this.connectionString = // get your connection string;
    }
}

// Better usage example
DatabaseConnection.OpenConnectionAnd(x => x.Execute(blah));

语法可能不完全正确,因为我只是在脑海中写上面的内容,但应该足够接近以便使用。


0

您可以查看数据访问模式来处理与SQL的所有接口。

这通常是推荐的方法,因此多个表单(或任何情况)可以访问检索和存储数据的相同方法。

这里有一个关于如何使用它的问题(附有答案)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接