3

哪种模式更适合SqlConnection对象?哪个性能更好?你们提供其他模式吗?

class DataAccess1 : IDisposable
{
    private SqlConnection connection;

    public DataAccess1(string connectionString)
    {
        connection = new SqlConnection(connectionString);
    }

    public void Execute(string query)
    {
        using (SqlCommand command = connection.CreateCommand())
        {
            command.CommandText = query;
            command.CommandType = CommandType.Text;
            // ...

            command.Connection.Open();
            command.ExecuteNonQuery();
            command.Connection.Close();
        }
    }

    public void Dispose()
    {
        connection.Dispose();
    }
}

VS

class DataAccess2 : IDisposable
{
    private string connectionString;

    public DataAccess2(string connectionString)
    {
        this.connectionString = connectionString;
    }

    public void Execute(string query)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            SqlCommand command = connection.CreateCommand();
            command.CommandText = query;
            command.CommandType = CommandType.Text;
            // ...

            command.Connection.Open();
            command.ExecuteNonQuery();
            command.Connection.Close();
        }
    }

    public void Dispose()
    {            
    }
}
4

4 回答 4

3

没有真正的方法可以回答这个问题。简短而规范的答案是,连接应该在工作单元的整个生命周期内保持活跃。因为我们无法知道它DataAccess是如何使用的(它是否存在于您的应用程序的生命周期中,或者您是否实例化它并在您做某事时释放它?),因此不可能给出具体的答案。

话虽这么说,我会推荐第一种模式,但DataAccess根据需要实例化和处理您的对象;不要将其保留超过必要的时间。

于 2010-07-31T16:00:27.373 回答
1

建议一起去DataAccess2。不过这是个人喜好。有些人甚至可能建议你的班级是static. 很难说一个比另一个性能更好。你在 的道路上IDisposable,这很棒。

我很乐意阅读和维护您问题中显示的两种样式。

考虑让您的 DAL 也能够从 .config 读取连接字符串,而不是只允许在构造函数中传递值。

public DataAccess2(string connStr)
{
    this.connectionString = connStr;
}
public DataAccess2()
{
    this.connectionString = 
            ConfigurationManager.ConnectionStrings["foo"].ConnectionString;
}

考虑将您的 SqlCommand 包装在 ausing中。

using (var conn = new SqlConnection(connectionString))
{
    using(var cmd = conn.CreateCommand())
    {

    }
}
于 2010-07-31T16:17:19.717 回答
0

我认为这取决于您的 DataAccess 对象打算如何使用,如果它在“使用”子句中使用,那么连接保证在完成后被处理掉。

但总的来说,我更喜欢第二种模式,因为 sql 连接是在 Execute 方法中创建和处理的,因此当您忘记处理 DataAccess 对象时,它不太可能保持打开状态。

考虑到 sql 连接可能是一种稀缺资源,我认为应该尽一切努力确保它们不会被浪费。

于 2010-07-31T16:16:11.220 回答
0

如果您进行并发调用,第一个将导致错误。第二个将确保您为每个命令使用干净的连接,从而产生更多的连接。

我同意上面的陈述,它取决于使用的场景,为了解决与第一个相关的问题我有一个需要使用这种模式的包装器,所以我设置了一个字段值 boolean 以显示正在执行命令在连接上已经“排队”执行下一个命令。

当然,在某些情况下,您可能更喜欢使用多个连接......

于 2010-07-31T16:25:08.987 回答