First, I think you should make your method generic. That is, your method shouldn't return object
, it should return T
:
private T ExecuteQuery<T>(int pConnectionID, string pSQL,
Func<IDbCommand, T> pQuery, IEnumerable<QueryParameter> pParams)
Now, what I think you should do is to add another overload of ExecuteQuery
specifically for collections:
private IEnumerable<T> ExecuteQuery<T>(int pConnectionID, string pSQL,
Func<IDbCommand, IEnumerable<T>> pQuery, IEnumerable<QueryParameter> pParams)
which would be implemented using yield return
itself. Something like:
using (IDbCommand command = connection.CreateCommand())
{
command.CommandText = pSQL;
if (pParams != null)
ApplyParameters(pParams, command);
foreach (var x in pQuery(command))
yield return x;
}
This way, the command will be disposed only after iteration of the result completes (or if it's aborted prematurely).
(I'm not completely sure about this, but there is a chance that overload resolution will pick the wrong overload for collections. In that case, rename the collection version to something like ExecuteQueryCollection
.)