RemoteGroupingResult ExecRemoteGrouping() { return RemoteGroupTransformer.Run( ExecExpr<AnonType>(Source, Builder.BuildLoadGroupsExpr(Source.Expression)), Options.HasGroups ? Options.Group.Length : 0, Options.TotalSummary, Options.GroupSummary ); }
static RemoteGroupingResult ExecRemoteGrouping <T>(IQueryable <T> source, DataSourceExpressionBuilder <T> builder, DataSourceLoadOptionsBase options) { return(RemoteGroupTransformer.Run( ExecQuery(builder.BuildLoadGroupsExpr().Compile(), source, options), options.HasGroups ? options.Group.Length : 0, options.TotalSummary, options.GroupSummary )); }
public LoadResult Load() { if (Context.IsCountQuery) { return new LoadResult { totalCount = ExecCount() } } ; var result = new LoadResult(); if (Context.UseRemoteGrouping && Context.ShouldEmptyGroups) { var groupingResult = ExecRemoteGrouping(); EmptyGroups(groupingResult.Groups, Context.Group.Count); result.data = Paginate(groupingResult.Groups, Context.Skip, Context.Take); result.summary = groupingResult.Totals; result.totalCount = groupingResult.TotalCount; if (Context.RequireGroupCount) { result.groupCount = groupingResult.Groups.Count(); } } else { var deferPaging = Context.HasGroups || !Context.UseRemoteGrouping && !Context.SummaryIsTotalCountOnly && Context.HasSummary; Expression loadExpr; if (!deferPaging && Context.PaginateViaPrimaryKey && Context.Skip > 0) { if (!Context.HasPrimaryKey) { throw new InvalidOperationException(nameof(DataSourceLoadOptionsBase.PaginateViaPrimaryKey) + " requires a primary key." + " Specify it via the " + nameof(DataSourceLoadOptionsBase.PrimaryKey) + " property."); } var loadKeysExpr = Builder.BuildLoadExpr(Source.Expression, true, selectOverride: Context.PrimaryKey); var keyTuples = ExecExpr <AnonType>(Source, loadKeysExpr); loadExpr = Builder.BuildLoadExpr(Source.Expression, false, filterOverride: FilterFromKeys(keyTuples)); } else { loadExpr = Builder.BuildLoadExpr(Source.Expression, !deferPaging); } if (Context.HasAnySelect) { ContinueWithGrouping( ExecWithSelect(loadExpr), result ); } else { ContinueWithGrouping( ExecExpr <S>(Source, loadExpr), result ); } if (deferPaging) { result.data = Paginate(result.data, Context.Skip, Context.Take); } if (Context.ShouldEmptyGroups) { EmptyGroups(result.data, Context.Group.Count); } } return(result); } IEnumerable <ExpandoObject> ExecWithSelect(Expression loadExpr) { if (Context.UseRemoteSelect) { return(SelectHelper.ConvertRemoteResult(ExecExpr <AnonType>(Source, loadExpr), Context.FullSelect)); } return(SelectHelper.Evaluate(ExecExpr <S>(Source, loadExpr), Context.FullSelect)); } void ContinueWithGrouping <R>(IEnumerable <R> loadResult, LoadResult result) { var accessor = new DefaultAccessor <R>(); if (Context.HasGroups) { var groups = new GroupHelper <R>(accessor).Group(loadResult, Context.Group); if (Context.RequireGroupCount) { result.groupCount = groups.Count; } ContinueWithAggregation(groups, accessor, result); } else { ContinueWithAggregation(loadResult, accessor, result); } } void ContinueWithAggregation <R>(IEnumerable data, IAccessor <R> accessor, LoadResult result) { if (Context.UseRemoteGrouping && !Context.SummaryIsTotalCountOnly && Context.HasSummary && !Context.HasGroups) { var groupingResult = ExecRemoteGrouping(); result.totalCount = groupingResult.TotalCount; result.summary = groupingResult.Totals; } else { var totalCount = -1; if (Context.RequireTotalCount || Context.SummaryIsTotalCountOnly) { totalCount = ExecCount(); } if (Context.RequireTotalCount) { result.totalCount = totalCount; } if (Context.SummaryIsTotalCountOnly) { result.summary = Enumerable.Repeat((object)totalCount, Context.TotalSummary.Count).ToArray(); } else if (Context.HasSummary) { data = Buffer <R>(data); result.summary = new AggregateCalculator <R>(data, accessor, Context.TotalSummary, Context.GroupSummary).Run(); } } result.data = data; } int ExecCount() { var expr = Builder.BuildCountExpr(Source.Expression); #if DEBUG ExpressionWatcher?.Invoke(expr); #endif return(Source.Provider.Execute <int>(expr)); } RemoteGroupingResult ExecRemoteGrouping() { return(RemoteGroupTransformer.Run( typeof(S), ExecExpr <AnonType>(Source, Builder.BuildLoadGroupsExpr(Source.Expression)), Context.HasGroups ? Context.Group.Count : 0, Context.TotalSummary, Context.GroupSummary )); } IEnumerable <R> ExecExpr <R>(IQueryable <S> source, Expression expr) { IEnumerable <R> result = source.Provider.CreateQuery <R>(expr); #if DEBUG if (UseEnumerableOnce) { result = new EnumerableOnce <R>(result); } ExpressionWatcher?.Invoke(expr); #endif return(result); } IList FilterFromKeys(IEnumerable <AnonType> keyTuples) { var result = new List <object>(); var key = Context.PrimaryKey; var keyLength = key.Count; foreach (var tuple in keyTuples) { if (result.Count > 0) { result.Add("or"); } void AddCondition(IList container, int index) { container.Add(new object[] { key[index], tuple[index] }); } if (keyLength == 1) { AddCondition(result, 0); } else { var group = new List <object>(); for (var i = 0; i < keyLength; i++) { AddCondition(group, i); } result.Add(group); } } return(result); }
public LoadResult Load() { if (Options.IsCountQuery) { return new LoadResult { totalCount = ExecCount() } } ; var result = new LoadResult(); if (CanUseRemoteGrouping && ShouldEmptyGroups) { var groupingResult = ExecRemoteGrouping(); EmptyGroups(groupingResult.Groups, Options.Group.Length); result.data = Paginate(groupingResult.Groups, Options.Skip, Options.Take); result.summary = groupingResult.Totals; result.totalCount = groupingResult.TotalCount; if (Options.RequireGroupCount) { result.groupCount = groupingResult.Groups.Count(); } } else { if (!Options.HasPrimaryKey) { Options.PrimaryKey = Utils.GetPrimaryKey(typeof(S)); } if (!Options.HasPrimaryKey && !Options.HasDefaultSort && (Options.Skip > 0 || Options.Take > 0)) { if (Compat.IsEntityFramework(Source.Provider)) { Options.DefaultSort = EFSorting.FindSortableMember(typeof(S)); } else if (Compat.IsXPO(Source.Provider)) { Options.DefaultSort = "this"; } } var deferPaging = Options.HasGroups || !CanUseRemoteGrouping && !SummaryIsTotalCountOnly && Options.HasSummary; var loadExpr = Builder.BuildLoadExpr(Source.Expression, !deferPaging); if (Options.HasAnySelect) { ContinueWithGrouping( ExecWithSelect(loadExpr).Select(ProjectionToExpando), result ); } else { ContinueWithGrouping( ExecExpr <S>(Source, loadExpr), result ); } if (deferPaging) { result.data = Paginate(result.data, Options.Skip, Options.Take); } if (ShouldEmptyGroups) { EmptyGroups(result.data, Options.Group.Length); } } return(result); } IEnumerable <AnonType> ExecWithSelect(Expression loadExpr) { if (Options.UseRemoteSelect) { return(ExecExpr <AnonType>(Source, loadExpr)); } var inMemoryQuery = ForceExecution(ExecExpr <S>(Source, loadExpr)).AsQueryable(); var selectExpr = new SelectExpressionCompiler <S>(true).Compile(inMemoryQuery.Expression, Options.GetFullSelect()); return(ExecExpr <AnonType>(inMemoryQuery, selectExpr)); } void ContinueWithGrouping <R>(IEnumerable <R> loadResult, LoadResult result) { var accessor = new DefaultAccessor <R>(); if (Options.HasGroups) { var groups = new GroupHelper <R>(accessor).Group(loadResult, Options.Group); if (Options.RequireGroupCount) { result.groupCount = groups.Count; } ContinueWithAggregation(groups, accessor, result); } else { ContinueWithAggregation(loadResult, accessor, result); } } void ContinueWithAggregation <R>(IEnumerable data, IAccessor <R> accessor, LoadResult result) { if (CanUseRemoteGrouping && !SummaryIsTotalCountOnly && Options.HasSummary && !Options.HasGroups) { var groupingResult = ExecRemoteGrouping(); result.totalCount = groupingResult.TotalCount; result.summary = groupingResult.Totals; } else { var totalCount = -1; if (Options.RequireTotalCount || SummaryIsTotalCountOnly) { totalCount = ExecCount(); } if (Options.RequireTotalCount) { result.totalCount = totalCount; } if (SummaryIsTotalCountOnly) { result.summary = Enumerable.Repeat((object)totalCount, Options.TotalSummary.Length).ToArray(); } else if (Options.HasSummary) { data = Buffer <R>(data); result.summary = new AggregateCalculator <R>(data, accessor, Options.TotalSummary, Options.GroupSummary).Run(); } } result.data = data; } int ExecCount() { var expr = Builder.BuildCountExpr(Source.Expression); #if DEBUG Options.ExpressionWatcher?.Invoke(expr); #endif return(Source.Provider.Execute <int>(expr)); } RemoteGroupingResult ExecRemoteGrouping() { return(RemoteGroupTransformer.Run( ExecExpr <AnonType>(Source, Builder.BuildLoadGroupsExpr(Source.Expression)), Options.HasGroups ? Options.Group.Length : 0, Options.TotalSummary, Options.GroupSummary )); } IEnumerable <R> ExecExpr <R>(IQueryable <S> source, Expression expr) { IEnumerable <R> result = source.Provider.CreateQuery <R>(expr); #if DEBUG if (Options.UseEnumerableOnce) { result = new EnumerableOnce <R>(result); } Options.ExpressionWatcher?.Invoke(expr); #endif return(result); }
public LoadResult Load() { if (Context.IsCountQuery) { return new LoadResult { totalCount = ExecCount() } } ; var result = new LoadResult(); if (Context.UseRemoteGrouping && Context.ShouldEmptyGroups) { var groupingResult = ExecRemoteGrouping(); EmptyGroups(groupingResult.Groups, Context.Group.Count); result.data = Paginate(groupingResult.Groups, Context.Skip, Context.Take); result.summary = groupingResult.Totals; result.totalCount = groupingResult.TotalCount; if (Context.RequireGroupCount) { result.groupCount = groupingResult.Groups.Count(); } } else { var deferPaging = Context.HasGroups || !Context.UseRemoteGrouping && !Context.SummaryIsTotalCountOnly && Context.HasSummary; var loadExpr = Builder.BuildLoadExpr(Source.Expression, !deferPaging); if (Context.HasAnySelect) { ContinueWithGrouping( ExecWithSelect(loadExpr), result ); } else { ContinueWithGrouping( ExecExpr <S>(Source, loadExpr), result ); } if (deferPaging) { result.data = Paginate(result.data, Context.Skip, Context.Take); } if (Context.ShouldEmptyGroups) { EmptyGroups(result.data, Context.Group.Count); } } return(result); } IEnumerable <ExpandoObject> ExecWithSelect(Expression loadExpr) { if (Context.UseRemoteSelect) { return(SelectHelper.ConvertRemoteResult(ExecExpr <AnonType>(Source, loadExpr), Context.FullSelect)); } return(SelectHelper.Evaluate(ExecExpr <S>(Source, loadExpr), Context.FullSelect)); } void ContinueWithGrouping <R>(IEnumerable <R> loadResult, LoadResult result) { var accessor = new DefaultAccessor <R>(); if (Context.HasGroups) { var groups = new GroupHelper <R>(accessor).Group(loadResult, Context.Group); if (Context.RequireGroupCount) { result.groupCount = groups.Count; } ContinueWithAggregation(groups, accessor, result); } else { ContinueWithAggregation(loadResult, accessor, result); } } void ContinueWithAggregation <R>(IEnumerable data, IAccessor <R> accessor, LoadResult result) { if (Context.UseRemoteGrouping && !Context.SummaryIsTotalCountOnly && Context.HasSummary && !Context.HasGroups) { var groupingResult = ExecRemoteGrouping(); result.totalCount = groupingResult.TotalCount; result.summary = groupingResult.Totals; } else { var totalCount = -1; if (Context.RequireTotalCount || Context.SummaryIsTotalCountOnly) { totalCount = ExecCount(); } if (Context.RequireTotalCount) { result.totalCount = totalCount; } if (Context.SummaryIsTotalCountOnly) { result.summary = Enumerable.Repeat((object)totalCount, Context.TotalSummary.Count).ToArray(); } else if (Context.HasSummary) { data = Buffer <R>(data); result.summary = new AggregateCalculator <R>(data, accessor, Context.TotalSummary, Context.GroupSummary).Run(); } } result.data = data; } int ExecCount() { var expr = Builder.BuildCountExpr(Source.Expression); #if DEBUG ExpressionWatcher?.Invoke(expr); #endif return(Source.Provider.Execute <int>(expr)); } RemoteGroupingResult ExecRemoteGrouping() { return(RemoteGroupTransformer.Run( typeof(S), ExecExpr <AnonType>(Source, Builder.BuildLoadGroupsExpr(Source.Expression)), Context.HasGroups ? Context.Group.Count : 0, Context.TotalSummary, Context.GroupSummary )); } IEnumerable <R> ExecExpr <R>(IQueryable <S> source, Expression expr) { IEnumerable <R> result = source.Provider.CreateQuery <R>(expr); #if DEBUG if (UseEnumerableOnce) { result = new EnumerableOnce <R>(result); } ExpressionWatcher?.Invoke(expr); #endif return(result); }