Reputation: 13397
I have created this generic method:
/// <summary>
/// Executes a list of items
/// </summary>
/// <param name="procedureName">The name of the procedure</param>
/// <param name="parameters">List of oracle parameters</param>
/// <param name="limit">The limit of the results to return</param>
/// <param name="mapper">The oracle mapper method</param>
/// <returns></returns>
protected async Task<IEnumerable<T>> ListAsync<T>(string procedureName, IList<OracleParameter> parameters, int limit, Func<IDataReader, T> mapper)
{
// Create our list
var models = new List<T>();
var counter = 0;
// Get our reader and return our model
using (var reader = await _oracleUnitOfWork.ExecuteReaderAsync(procedureName, parameters))
{
// While we have rows and our counter
while (reader.Read() && ((counter < limit || limit == 0) || limit == 0))
{
// If we have a limit, increase our counter (this is first to stop 0 based index messing the amount of objects to return)
if (limit > 0)
counter++;
// Get our item from the database
models.Add(mapper(reader));
}
}
// Return our list
return models;
}
Which I can invoke like this:
return await ListAsync("IBPA_MANFCOMPLAINT.complaintSearch", parameters, yield, OracleMapper.Complaint.Map);
But I want to extend this a little. The Mapper just uses the IDataReader to assign the column values to the model properties. For stock instead of using this:
return await ListAsync("ibpa_stock.readRelatedLotstoLot", parameters, 0, OracleMapper.Stock.Map);
I want to do a get request, a bit like this:
return await ListAsync("ibpa_stock.readRelatedLotstoLot", parameters, 0, async (reader) => await GetAsync(reader["lotno"].ToString()));
What can I do to keep things DRY, but at the same time to allow that invocation?
Upvotes: 1
Views: 452
Reputation: 203847
You'll need to have two overloads of the method, one that accepts a Func<IDataReader, T>
, and one that accepts a Func<IDataReader, Task<T>>
. The second one will need to await
the method call when it invokes it, the former won't.
Upvotes: 1