У меня есть базовый класс для классов доступа к данным. Этот класс реализует 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();
}
}
}
Классы, наследующие от этого класса, фактически обращаются к базе данных:
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;
}
}
Классы, которые используют FooDAL, используют шаблон using, чтобы гарантировать, что Dispose вызывается в FooDAL с таким кодом, как это:
using(FooDAL dal = new FooDAL())
{
return dal.CreateFoo();
}
Мой вопрос: гарантирует ли это, что IDbCommand также удаляется должным образом, даже если он не заключен в шаблон using или try-finally? Что произойдет, если во время выполнения команды возникнет исключение?
Кроме того, было бы лучше создать экземпляр соединения в CreateFoo, а не в конструкторе базового класса по соображениям производительности?
Любая помощь приветствуется.