execution options.

This commit is contained in:
David Lebee
2019-11-27 20:08:51 -06:00
parent 3d58f0496d
commit 9c0a05b579
15 changed files with 312 additions and 58 deletions
+25 -4
View File
@@ -43,14 +43,23 @@ namespace PoweredSoft.DynamicQuery
ApplySorting<TSource>();
ApplyPaging<TSource>();
// create group & select expression.
CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb => finalGroups.ForEach((fg, index) => gb.Path(fg.Path, $"Key_{index}")));
if (Options.GroupByInMemory)
CurrentQueryable = CurrentQueryable.ToObjectList().Cast<TSource>().AsQueryable();
CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb =>
{
gb.NullChecking(Options.GroupByInMemory ? Options.GroupByInMemoryNullCheck : false);
finalGroups.ForEach((fg, index) => gb.Path(fg.Path, $"Key_{index}"));
});
CurrentQueryable = CurrentQueryable.Select(sb =>
{
sb.NullChecking(Options.GroupByInMemory ? Options.GroupByInMemoryNullCheck : false);
finalGroups.ForEach((fg, index) => sb.Key($"Key_{index}", $"Key_{index}"));
sb.ToList("Records");
});
// loop through the grouped records.
var groupRecords = CurrentQueryable.ToDynamicClassList();
@@ -118,13 +127,25 @@ namespace PoweredSoft.DynamicQuery
public IQueryExecutionResult<TSource> Execute<TSource>(IQueryable<TSource> queryable, IQueryCriteria criteria)
{
Reset(queryable, criteria);
Reset(queryable, criteria, new QueryExecutionOptions());
return FinalExecute<TSource, TSource>();
}
public IQueryExecutionResult<TRecord> Execute<TSource, TRecord>(IQueryable<TSource> queryable, IQueryCriteria criteria)
{
Reset(queryable, criteria);
Reset(queryable, criteria, new QueryExecutionOptions());
return FinalExecute<TSource, TRecord>();
}
public IQueryExecutionResult<TSource> Execute<TSource>(IQueryable<TSource> queryable, IQueryCriteria criteria, IQueryExecutionOptions options)
{
Reset(queryable, criteria, options);
return FinalExecute<TSource, TSource>();
}
public IQueryExecutionResult<TRecord> Execute<TSource, TRecord>(IQueryable<TSource> queryable, IQueryCriteria criteria, IQueryExecutionOptions options)
{
Reset(queryable, criteria, options);
return FinalExecute<TSource, TRecord>();
}
}
+54 -14
View File
@@ -20,7 +20,7 @@ namespace PoweredSoft.DynamicQuery
AsyncQueryableService = asyncQueryableService;
}
protected virtual Task<IQueryExecutionResult<TRecord>> FinalExecuteAsync<TSource, TRecord>(CancellationToken cancellationToken = default(CancellationToken))
protected virtual Task<IQueryExecutionResult<TRecord>> FinalExecuteAsync<TSource, TRecord>(CancellationToken cancellationToken = default)
{
CommonBeforeExecute<TSource>();
return HasGrouping ? ExecuteAsyncGrouping<TSource, TRecord>(cancellationToken) : ExecuteAsyncNoGrouping<TSource, TRecord>(cancellationToken);
@@ -50,16 +50,44 @@ namespace PoweredSoft.DynamicQuery
ApplySorting<TSource>();
ApplyPaging<TSource>();
// create group & select expression.
CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb => finalGroups.ForEach((fg, index) => gb.Path(fg.Path, $"Key_{index}")));
CurrentQueryable = CurrentQueryable.Select(sb =>
{
finalGroups.ForEach((fg, index) => sb.Key($"Key_{index}", $"Key_{index}"));
sb.ToList("Records");
});
List<DynamicClass> groupRecords;
// loop through the grouped records.
var groupRecords = await AsyncQueryableService.ToListAsync(CurrentQueryable.Cast<DynamicClass>(), cancellationToken);
if (Options.GroupByInMemory)
{
CurrentQueryable = CurrentQueryable.ToObjectList().Cast<TSource>().AsQueryable();
// create group & select expression.
CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb =>
{
gb.NullChecking(Options.GroupByInMemory ? Options.GroupByInMemoryNullCheck : false);
finalGroups.ForEach((fg, index) => gb.Path(fg.Path, $"Key_{index}"));
});
CurrentQueryable = CurrentQueryable.Select(sb =>
{
sb.NullChecking(Options.GroupByInMemory ? Options.GroupByInMemoryNullCheck : false);
finalGroups.ForEach((fg, index) => sb.Key($"Key_{index}", $"Key_{index}"));
sb.ToList("Records");
});
// loop through the grouped records.
groupRecords = CurrentQueryable.Cast<DynamicClass>().ToList();
}
else
{
// create group & select expression.
CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb =>
{
finalGroups.ForEach((fg, index) => gb.Path(fg.Path, $"Key_{index}"));
});
CurrentQueryable = CurrentQueryable.Select(sb =>
{
finalGroups.ForEach((fg, index) => sb.Key($"Key_{index}", $"Key_{index}"));
sb.ToList("Records");
});
// loop through the grouped records.
groupRecords = await AsyncQueryableService.ToListAsync(CurrentQueryable.Cast<DynamicClass>(), cancellationToken);
}
// now join them into logical collections
var lastLists = new List<(List<TSource> entities, IGroupQueryResult<TRecord> group)>();
@@ -127,15 +155,27 @@ namespace PoweredSoft.DynamicQuery
return finalResult;
}
public Task<IQueryExecutionResult<TSource>> ExecuteAsync<TSource>(IQueryable<TSource> queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default(CancellationToken))
public Task<IQueryExecutionResult<TSource>> ExecuteAsync<TSource>(IQueryable<TSource> queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default)
{
Reset(queryable, criteria);
Reset(queryable, criteria, new QueryExecutionOptions());
return FinalExecuteAsync<TSource, TSource>(cancellationToken);
}
public Task<IQueryExecutionResult<TRecord>> ExecuteAsync<TSource, TRecord>(IQueryable<TSource> queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default(CancellationToken))
public Task<IQueryExecutionResult<TRecord>> ExecuteAsync<TSource, TRecord>(IQueryable<TSource> queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default)
{
Reset(queryable, criteria);
Reset(queryable, criteria, new QueryExecutionOptions());
return FinalExecuteAsync<TSource, TRecord>(cancellationToken);
}
public Task<IQueryExecutionResult<TSource>> ExecuteAsync<TSource>(IQueryable<TSource> queryable, IQueryCriteria criteria, IQueryExecutionOptions options, CancellationToken cancellationToken = default)
{
Reset(queryable, criteria, options);
return FinalExecuteAsync<TSource, TSource>(cancellationToken);
}
public Task<IQueryExecutionResult<TRecord>> ExecuteAsync<TSource, TRecord>(IQueryable<TSource> queryable, IQueryCriteria criteria, IQueryExecutionOptions options, CancellationToken cancellationToken = default)
{
Reset(queryable, criteria, options);
return FinalExecuteAsync<TSource, TRecord>(cancellationToken);
}
}
+13 -1
View File
@@ -20,24 +20,36 @@ namespace PoweredSoft.DynamicQuery
protected IQueryCriteria Criteria { get; set; }
protected IQueryable QueryableAtStart { get; private set; }
protected IQueryable CurrentQueryable { get; set; }
protected IQueryExecutionOptions Options { get; private set; }
protected Type QueryableUnderlyingType => QueryableAtStart.ElementType;
protected bool HasGrouping => Criteria.Groups?.Any() == true;
protected bool HasPaging => Criteria.PageSize.HasValue && Criteria.PageSize > 0;
protected virtual void Reset(IQueryable queryable, IQueryCriteria criteria)
protected virtual void Reset(IQueryable queryable, IQueryCriteria criteria, IQueryExecutionOptions options)
{
Criteria = criteria ?? throw new ArgumentNullException("criteria");
QueryableAtStart = queryable ?? throw new ArgumentNullException("queryable");
CurrentQueryable = QueryableAtStart;
Options = options;
}
protected virtual void CommonBeforeExecute<TSource>()
{
ApplyQueryExecutionOptionIncerceptors();
ApplyIncludeStrategyInterceptors<TSource>();
ApplyBeforeFilterInterceptors<TSource>();
ApplyFilters<TSource>();
}
protected virtual void ApplyQueryExecutionOptionIncerceptors()
{
Options = Interceptors
.Where(t => t is IQueryExecutionOptionsInterceptor)
.Cast<IQueryExecutionOptionsInterceptor>()
.Aggregate(Options, (prev, curr) => curr.InterceptQueryExecutionOptions(CurrentQueryable, prev));
}
public virtual void AddInterceptor(IQueryInterceptor interceptor)
{
if (interceptor == null) throw new ArgumentNullException("interceptor");