哪种模式更适合SqlConnection对象?

时间:2010-07-31 15:55:49

标签: c# performance sqlconnection sqlcommand

哪种模式更适合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 个答案:

答案 0 :(得分:3)

没有真正的方法来回答这个问题。简短的,规范的答案是连接应该在您的工作单元的整个生命周期内保持活跃。因为我们无法知道如何使用DataAccess(它是否存在于应用程序的生命周期中,或者您实例化它并在您执行某些操作时将其丢弃?),所以无法给出具体的答案。 / p>

话虽这么说,我会推荐第一个模式,但是根据需要实例化并处理你的DataAccess对象;不要把它保持在必要的时间以上。

答案 1 :(得分:1)

建议使用DataAccess2。这是个人偏好。有些人甚至可能会建议你的班级为static。很难说一个人比另一个人表现得更好。你正走在IDisposable的道路上,这很棒。

我很乐意在您的问题中阅读和维护上面显示的两种风格。

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

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

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

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

    }
}

答案 2 :(得分:0)

我认为这取决于您的DataAccess对象的使用方式,如果它在'using'子句中使用,那么保证连接完成后将被处理掉。

但总的来说,我更喜欢第二种模式,因为sql连接是在Execute方法中创建和处理的,所以当你忘记丢弃DataAccess对象时,它不太可能被打开。

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

答案 3 :(得分:0)

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

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

当然会出现您可能更喜欢使用多个连接的情况......