IDbCommand是否在实现IDisposable的类中被处置?

时间:2022-06-07 16:58:46

I have a base class for data access classes. This class implements IDisposable. This base class contains the IDbConnection and instantiates it in the constructor.

我有一个数据访问类的基类。这个类实现了IDisposable。此基类包含IDbConnection并在构造函数中实例化它。

public class DALBase : IDisposable
{
    protected IDbConnection cn;
    public DALBase()
    {
        cn = new MySqlConnection(connString);
    }
    public void Dispose()
    {
        if (cn != null)
        {
            if (cn.State != ConnectionState.Closed)
            {
                try
                {
                    cn.Close();
                }
                catch
                {
                }
            }
            cn.Dispose();
        }
    }
}

Classes that inherit from this class actually access the database:

从此类继承的类实际访问数据库:

public class FooDAL : DALBase
{
    public int CreateFoo()
    {
        // Notice that the cmd here is not wrapped in a using or try-finally.
        IDbCommand cmd = CreateCommand("create foo with sql", cn);
        Open();
        int ident = int.Parse(cmd.ExecuteScalar().ToString());
        Close();
        cmd.Dispose();
        return ident;
    }
}

Classes that use FooDAL use the using pattern to ensure that Dispose gets called on the FooDAL with code like this:

使用FooDAL的类使用using模式来确保在FooDAL上使用以下代码调用Dispose:

using(FooDAL dal = new FooDAL())
{
    return dal.CreateFoo();
}

My question is, does this also ensure that the IDbCommand is disposed of properly even though it's not wrapped in a using pattern or try-finally? What happens if an exception occurs during the execution of the command?

我的问题是,这是否也确保IDbCommand被正确处理掉,即使它没有包含在使用模式或try-finally中?如果在执行命令期间发生异常会发生什么?

Also, would it be better to instantiate the connection in CreateFoo instead of in the constructor of the base class for performance reasons?

另外,出于性能原因,在CreateFoo中而不是在基类的构造函数中实例化连接会更好吗?

Any help is appreciated.

任何帮助表示赞赏。

2 个解决方案

#1


2  

Given that the connections are pooled, just create the MySqlConnection in the CreateFOO method (with a using block).

鉴于连接是池,只需在CreateFOO方法中创建MySqlConnection(使用using块)。

Don't bother about closing it, as it will be disposed/closed automatically at the end of the using block.

不要打扰关闭它,因为它将在使用块的末端自动处理/关闭。

public int CreateFoo()
{
    using (var cn = new MySqlConnection(connString))
    {
        // Notice that the cmd here is not wrapped in a using or try-finally.
        using (IDbCommand cmd = CreateCommand("create foo with sql", cn))
        {
            cn.Open();
            return int.Parse(cmd.ExecuteScalar().ToString());
        }
     }
}

#2


0  

If this is all in the interest of efficiency, the biggest change you can make to speed up your code is to avoid opening and closing the db connection object on each DbCommand.

如果这一切都符合效率的要求,那么加速代码的最大变化就是避免在每个DbCommand上打开和关闭数据库连接对象。

#1


2  

Given that the connections are pooled, just create the MySqlConnection in the CreateFOO method (with a using block).

鉴于连接是池,只需在CreateFOO方法中创建MySqlConnection(使用using块)。

Don't bother about closing it, as it will be disposed/closed automatically at the end of the using block.

不要打扰关闭它,因为它将在使用块的末端自动处理/关闭。

public int CreateFoo()
{
    using (var cn = new MySqlConnection(connString))
    {
        // Notice that the cmd here is not wrapped in a using or try-finally.
        using (IDbCommand cmd = CreateCommand("create foo with sql", cn))
        {
            cn.Open();
            return int.Parse(cmd.ExecuteScalar().ToString());
        }
     }
}

#2


0  

If this is all in the interest of efficiency, the biggest change you can make to speed up your code is to avoid opening and closing the db connection object on each DbCommand.

如果这一切都符合效率的要求,那么加速代码的最大变化就是避免在每个DbCommand上打开和关闭数据库连接对象。