So, I am using Repository
pattern with Dapper and ADO.NET. I have my based DB infrastructure setup as follows:
public class ConnectionFactory: IConnectionFactory
{
private readonly string dbConnectionString = Convert.ToString(ConfigurationManager.ConnectionStrings["MyDBConn"].ConnectionString);
private MySqlConnection _dbConnection;
public IDbConnection GetDBConnection
{
get
{
if(string.IsNullOrEmpty(dbConnectionString))
{
throw new ArgumentNullException("DB Connection string received a null argument!");
}
if (_dbConnection == null)
{
_dbConnection = new MySqlConnection(dbConnectionString);
}
if (_dbConnection.State != ConnectionState.Open)
{
_dbConnection.Open();
}
return _dbConnection;
}
}
public void CloseDBConnection()
{
if (_dbConnection != null && _dbConnection.State == ConnectionState.Open)
{
_dbConnection.Close();
}
}
}
And I have a Repository
class that uses this infrastructure:
public async Task<IEnumerable<UserInformation>> GetUserInformation()
{
IEnumerable<UserInformation> list;
string querystring = "SELECT * FROM users WHERE valid=1;";
try
{
list = await SqlMapper.QueryAsync<UserInformation>(_connectionFactory.GetDBConnection, querystring, param, commandType: CommandType.Text);
}
finally
{
_connectionFactory.CloseDBConnection();
}
return list;
}
For reading my IReader
and converting to a dataset, I do the following:
public async Task<DataSet> GetOrderDetails(int oid)
{
DataSet dataset = new DataSet();
string querystring = "select * from orders WHERE OrderId=@oid";
DynamicParameters param = new DynamicParameters();
param.Add("@oid", oid);
using (var list = await SqlMapper.ExecuteReaderAsync(_connectionFactory.GetDBConnection, querystring, param, commandType: CommandType.Text))
{
dataset = helper.ConvertDataReaderToDataSet(list);
}
return dataset;
}
Here ConvertDataReaderToDataSet
is a method that only converts the IReader
to a Dataset
.
The problem that I having is that I am getting the following error after a while (from logs):
2/10/2021 12:37:44 AM
Type: Exception
Error Message: error connecting: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Method Name: GetOrderDetails
I have researched this error and it suggests a memory leak. Can you guys help me identify what is the problem and review my DB infrastructure setup?
Edit: After a discussion, I have changed the implementation to this:
public async Task<IEnumerable<UserInformation>> GetUserInformation()
{
IEnumerable<UserInformation> list;
string querystring = "SELECT * FROM users WHERE valid=1;";
using (var conn = new MySqlConnection(dbConnectionString))
{
list = await conn.QueryAsync<UserInformation>(querystring, commandType: CommandType.Text);
}
return list;
}
_dbConnectionString
is not a string. It's a connection. \$\endgroup\$GetUserInformation
, and the broken version is not discussed in an answer, there is no reason to keep the broken version in the question. \$\endgroup\$