Skip to content

Commit fa4f9de

Browse files
author
electricessence
committed
More overloads for using ValueTuples.
1 parent 9747fec commit fa4f9de

7 files changed

Lines changed: 545 additions & 184 deletions

Documentation.xml

Lines changed: 161 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ExpressiveAsyncCommandBase.cs

Lines changed: 107 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -126,59 +126,59 @@ public Task<List<T>> TakeAsync<T>(Func<IDataRecord, T> transform, int count)
126126
/// <returns>The task that completes when the iteration is done or the predicate evaluates false.</returns>
127127
public abstract Task IterateReaderAsyncWhile(Func<IDataRecord, Task<bool>> predicate);
128128

129-
/// <summary>
130-
/// Asynchronously iterates all records within the first result set using an IDataReader and returns the results.
131-
/// </summary>
132-
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
133-
public abstract Task<QueryResult<Queue<object[]>>> RetrieveAsync();
134-
135-
/// <summary>
136-
/// Asynchronously iterates all records within the current result set using an IDataReader and returns the desired results.
137-
/// </summary>
138-
/// <param name="ordinals">The ordinals to request from the reader for each record.</param>
139-
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
140-
public abstract Task<QueryResult<Queue<object[]>>> RetrieveAsync(IEnumerable<int> ordinals);
141-
142-
/// <summary>
143-
/// Asynchronously iterates all records within the current result set using an IDataReader and returns the desired results.
144-
/// </summary>
145-
/// <param name="n">The first ordinal to include in the request to the reader for each record.</param>
146-
/// <param name="others">The remaining ordinals to request from the reader for each record.</param>
147-
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
148-
public Task<QueryResult<Queue<object[]>>> RetrieveAsync(int n, params int[] others)
149-
=> RetrieveAsync(new int[1] { n }.Concat(others));
150-
151-
/// <summary>
152-
/// Iterates all records within the first result set using an IDataReader and returns the desired results as a list of Dictionaries containing only the specified column values.
153-
/// </summary>
154-
/// <param name="columnNames">The column names to select.</param>
155-
/// <param name="normalizeColumnOrder">Orders the results arrays by ordinal.</param>
156-
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
157-
public abstract Task<QueryResult<Queue<object[]>>> RetrieveAsync(IEnumerable<string> columnNames, bool normalizeColumnOrder = false);
158-
159-
/// <summary>
160-
/// Iterates all records within the current result set using an IDataReader and returns the desired results.
161-
/// </summary>
162-
/// <param name="c">The first column name to include in the request to the reader for each record.</param>
163-
/// <param name="others">The remaining column names to request from the reader for each record.</param>
164-
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
165-
public Task<QueryResult<Queue<object[]>>> RetrieveAsync(string c, params string[] others)
166-
=> RetrieveAsync(new string[1] { c }.Concat(others));
167-
168-
/// <summary>
169-
/// Posts all transformed records to the provided target block.
170-
/// If .Complete is called on the target block, then the iteration stops.
171-
/// </summary>
172-
/// <typeparam name="T">The return type of the transform function.</typeparam>
173-
/// <param name="transform">The transform function to process each IDataRecord.</param>
174-
/// <param name="target">The target block to receive the records.</param>
175-
/// <returns>A task that is complete once there are no more results.</returns>
176-
public Task ToTargetBlockAsync<T>(ITargetBlock<T> target, Func<IDataRecord, T> transform)
129+
/// <summary>
130+
/// Asynchronously iterates all records within the first result set using an IDataReader and returns the results.
131+
/// </summary>
132+
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
133+
public abstract Task<QueryResult<Queue<object[]>>> RetrieveAsync();
134+
135+
/// <summary>
136+
/// Asynchronously iterates all records within the current result set using an IDataReader and returns the desired results.
137+
/// </summary>
138+
/// <param name="ordinals">The ordinals to request from the reader for each record.</param>
139+
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
140+
public abstract Task<QueryResult<Queue<object[]>>> RetrieveAsync(IEnumerable<int> ordinals);
141+
142+
/// <summary>
143+
/// Asynchronously iterates all records within the current result set using an IDataReader and returns the desired results.
144+
/// </summary>
145+
/// <param name="n">The first ordinal to include in the request to the reader for each record.</param>
146+
/// <param name="others">The remaining ordinals to request from the reader for each record.</param>
147+
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
148+
public Task<QueryResult<Queue<object[]>>> RetrieveAsync(int n, params int[] others)
149+
=> RetrieveAsync(new int[1] { n }.Concat(others));
150+
151+
/// <summary>
152+
/// Iterates all records within the first result set using an IDataReader and returns the desired results as a list of Dictionaries containing only the specified column values.
153+
/// </summary>
154+
/// <param name="columnNames">The column names to select.</param>
155+
/// <param name="normalizeColumnOrder">Orders the results arrays by ordinal.</param>
156+
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
157+
public abstract Task<QueryResult<Queue<object[]>>> RetrieveAsync(IEnumerable<string> columnNames, bool normalizeColumnOrder = false);
158+
159+
/// <summary>
160+
/// Iterates all records within the current result set using an IDataReader and returns the desired results.
161+
/// </summary>
162+
/// <param name="c">The first column name to include in the request to the reader for each record.</param>
163+
/// <param name="others">The remaining column names to request from the reader for each record.</param>
164+
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
165+
public Task<QueryResult<Queue<object[]>>> RetrieveAsync(string c, params string[] others)
166+
=> RetrieveAsync(new string[1] { c }.Concat(others));
167+
168+
/// <summary>
169+
/// Posts all transformed records to the provided target block.
170+
/// If .Complete is called on the target block, then the iteration stops.
171+
/// </summary>
172+
/// <typeparam name="T">The return type of the transform function.</typeparam>
173+
/// <param name="transform">The transform function to process each IDataRecord.</param>
174+
/// <param name="target">The target block to receive the records.</param>
175+
/// <returns>A task that is complete once there are no more results.</returns>
176+
public Task ToTargetBlockAsync<T>(ITargetBlock<T> target, Func<IDataRecord, T> transform)
177177
{
178178
Task<bool> lastSend = null;
179179
return IterateReaderAsyncWhile(async r =>
180180
{
181-
if (lastSend!=null && !await lastSend) return false;
181+
if (lastSend != null && !await lastSend) return false;
182182
lastSend = target.SendAsync(transform(r));
183183
return true;
184184
});
@@ -205,33 +205,73 @@ public ISourceBlock<T> AsSourceBlockAsync<T>(Func<IDataRecord, T> transform)
205205
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
206206
/// <param name="fieldMappingOverrides">An override map of field names to column names where the keys are the property names, and values are the column names.</param>
207207
/// <returns>A transform block that is recieving the results.</returns>
208-
public abstract ISourceBlock<T> AsSourceBlockAsync<T>(IEnumerable<KeyValuePair<string, string>> fieldMappingOverrides)
209-
where T : new();
208+
public abstract ISourceBlock<T> AsSourceBlockAsync<T>(IEnumerable<(string Field, string Column)> fieldMappingOverrides)
209+
where T : new();
210+
211+
/// <summary>
212+
/// Returns a source block as the source of records.
213+
/// </summary>
214+
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
215+
/// <param name="fieldMappingOverrides">An override map of field names to column names where the keys are the property names, and values are the column names.</param>
216+
/// <returns>A transform block that is recieving the results.</returns>
217+
public ISourceBlock<T> AsSourceBlockAsync<T>(IEnumerable<KeyValuePair<string, string>> fieldMappingOverrides)
218+
where T : new()
219+
=> AsSourceBlockAsync<T>(fieldMappingOverrides?.Select(kvp => (kvp.Key, kvp.Value)));
220+
221+
/// <summary>
222+
/// Returns a source block as the source of records.
223+
/// </summary>
224+
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
225+
/// <param name="fieldMappingOverrides">An override map of field names to column names where the keys are the property names, and values are the column names.</param>
226+
/// <returns>A transform block that is recieving the results.</returns>
227+
public ISourceBlock<T> AsSourceBlockAsync<T>(params (string Field, string Column)[] fieldMappingOverrides)
228+
where T : new()
229+
=> AsSourceBlockAsync<T>((IEnumerable<(string Field, string Column)>)fieldMappingOverrides);
230+
210231

211232
/// <summary>
212233
/// Asynchronously returns all records via a transform function.
213234
/// </summary>
214235
/// <param name="transform">The desired column names.</param>
215236
/// <returns>A task containing the list of results.</returns>
216237
public async Task<List<T>> ToListAsync<T>(Func<IDataRecord, T> transform)
217-
{
218-
var results = new List<T>();
219-
await IterateReaderAsync(record => results.Add(transform(record)));
220-
return results;
221-
}
222-
223-
/// <summary>
224-
/// Asynchronously returns all records and iteratively attempts to map the fields to type T.
225-
/// </summary>
238+
{
239+
var results = new List<T>();
240+
await IterateReaderAsync(record => results.Add(transform(record)));
241+
return results;
242+
}
243+
244+
/// <summary>
245+
/// Asynchronously returns all records and iteratively attempts to map the fields to type T.
246+
/// </summary>
226247
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
227248
/// <param name="fieldMappingOverrides">An override map of field names to column names where the keys are the property names, and values are the column names.</param>
228-
/// <returns>A task containing the list of results.</returns>
229-
public async Task<IEnumerable<T>> ResultsAsync<T>(IEnumerable<KeyValuePair<string, string>> fieldMappingOverrides = null) where T : new()
230-
{
231-
var x = new Transformer<T>(fieldMappingOverrides);
232-
return x.AsDequeueingEnumerable(await RetrieveAsync(x.ColumnNames));
233-
}
249+
/// <returns>A task containing the list of results.</returns>
250+
public async Task<IEnumerable<T>> ResultsAsync<T>(IEnumerable<(string Field, string Column)> fieldMappingOverrides) where T : new()
251+
{
252+
var x = new Transformer<T>(fieldMappingOverrides);
253+
return x.AsDequeueingEnumerable(await RetrieveAsync(x.ColumnNames));
254+
}
234255

256+
/// <summary>
257+
/// Asynchronously returns all records and iteratively attempts to map the fields to type T.
258+
/// </summary>
259+
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
260+
/// <param name="fieldMappingOverrides">An override map of field names to column names where the keys are the property names, and values are the column names.</param>
261+
/// <returns>A task containing the list of results.</returns>
262+
public Task<IEnumerable<T>> ResultsAsync<T>(IEnumerable<KeyValuePair<string, string>> fieldMappingOverrides) where T : new()
263+
=> ResultsAsync<T>(fieldMappingOverrides?.Select(kvp => (kvp.Key, kvp.Value)));
235264

236-
}
265+
/// <summary>
266+
/// Asynchronously returns all records and iteratively attempts to map the fields to type T.
267+
/// </summary>
268+
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
269+
/// <param name="fieldMappingOverrides">An override map of field names to column names where the keys are the property names, and values are the column names.</param>
270+
/// <returns>A task containing the list of results.</returns>
271+
public async Task<IEnumerable<T>> ResultsAsync<T>(params (string Field, string Column)[] fieldMappingOverrides) where T : new()
272+
{
273+
var x = new Transformer<T>(fieldMappingOverrides);
274+
return x.AsDequeueingEnumerable(await RetrieveAsync(x.ColumnNames));
275+
}
276+
}
237277
}

ExpressiveCommandBase.cs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,29 @@ public QueryResult<Queue<object[]>> Retrieve(string c, params string[] others)
444444
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
445445
/// <param name="fieldMappingOverrides">An optional override map of field names to column names where the keys are the property names, and values are the column names.</param>
446446
/// <returns>The enumerable to pull the transformed results from.</returns>
447-
public IEnumerable<T> Results<T>(IEnumerable<KeyValuePair<string, string>> fieldMappingOverrides = null)
447+
public IEnumerable<T> Results<T>(IEnumerable<KeyValuePair<string, string>> fieldMappingOverrides)
448+
where T : new()
449+
=> Execute(command => command.Results<T>(fieldMappingOverrides));
450+
451+
/// <summary>
452+
/// Iterates each record and attempts to map the fields to type T.
453+
/// Data is temporarily stored (buffered in entirety) in a queue of dictionaries before applying the transform for each iteration.
454+
/// </summary>
455+
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
456+
/// <param name="fieldMappingOverrides">An optional override map of field names to column names where the keys are the property names, and values are the column names.</param>
457+
/// <returns>The enumerable to pull the transformed results from.</returns>
458+
public IEnumerable<T> Results<T>(IEnumerable<(string Field, string Column)> fieldMappingOverrides)
459+
where T : new()
460+
=> Execute(command => command.Results<T>(fieldMappingOverrides));
461+
462+
/// <summary>
463+
/// Iterates each record and attempts to map the fields to type T.
464+
/// Data is temporarily stored (buffered in entirety) in a queue of dictionaries before applying the transform for each iteration.
465+
/// </summary>
466+
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
467+
/// <param name="fieldMappingOverrides">An optional override map of field names to column names where the keys are the property names, and values are the column names.</param>
468+
/// <returns>The enumerable to pull the transformed results from.</returns>
469+
public IEnumerable<T> Results<T>(params (string Field, string Column)[] fieldMappingOverrides)
448470
where T : new()
449471
=> Execute(command => command.Results<T>(fieldMappingOverrides));
450472

@@ -488,7 +510,7 @@ void i()
488510
/// If set to true, the command runs synchronusly and all data is acquired before the method returns.
489511
/// If set to false (default) the data is recieved asynchronously (data will be subsequently posted) and the source block (transform) can be completed early.</param>
490512
/// <returns>A transform block that is recieving the results.</returns>
491-
public ISourceBlock<T> AsSourceBlock<T>(IEnumerable<KeyValuePair<string, string>> fieldMappingOverrides, bool synchronousExecution = false)
513+
public ISourceBlock<T> AsSourceBlock<T>(IEnumerable<(string Field, string Column)> fieldMappingOverrides, bool synchronousExecution = false)
492514
where T : new()
493515
{
494516
var x = new Transformer<T>(fieldMappingOverrides);
@@ -515,6 +537,28 @@ void i() => ExecuteReader(reader =>
515537
return q;
516538
}
517539

540+
/// <summary>
541+
/// Provides a transform block as the source of records.
542+
/// </summary>
543+
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
544+
/// <param name="fieldMappingOverrides">An override map of field names to column names where the keys are the property names, and values are the column names.</param>
545+
/// <param name="synchronousExecution">By default the command is deferred.
546+
/// If set to true, the command runs synchronusly and all data is acquired before the method returns.
547+
/// If set to false (default) the data is recieved asynchronously (data will be subsequently posted) and the source block (transform) can be completed early.</param>
548+
/// <returns>A transform block that is recieving the results.</returns>
549+
public ISourceBlock<T> AsSourceBlock<T>(IEnumerable<KeyValuePair<string, string>> fieldMappingOverrides, bool synchronousExecution = false)
550+
where T : new()
551+
=> AsSourceBlock<T>(fieldMappingOverrides?.Select(kvp => (kvp.Key, kvp.Value)), synchronousExecution);
552+
553+
/// <summary>
554+
/// Provides a transform block as the source of records.
555+
/// </summary>
556+
/// <typeparam name="T">The model type to map the values to (using reflection).</typeparam>
557+
/// <param name="fieldMappingOverrides">An override map of field names to column names where the keys are the property names, and values are the column names.</param>
558+
/// <returns>A transform block that is recieving the results.</returns>
559+
public ISourceBlock<T> AsSourceBlock<T>(params (string Field, string Column)[] fieldMappingOverrides)
560+
where T : new()
561+
=> AsSourceBlock<T>((IEnumerable<(string Field, string Column)>)fieldMappingOverrides);
518562

519563
}
520564
}

0 commit comments

Comments
 (0)