public void FindSortableMember() { Assert.Null(EFSorting.FindSortableMember(typeof(TestClass_Base))); Assert.Equal("Key", EFSorting.FindSortableMember(typeof(TestClass_LikelyKey))); Assert.Equal("Key", EFSorting.FindSortableMember(typeof(TestClass_Field))); Assert.Equal("Sortable", EFSorting.FindSortableMember(typeof(TestClass_OtherSortable))); Assert.Equal("Sortable", EFSorting.FindSortableMember(typeof(TestClass_Nullable))); // see https://msdn.microsoft.com/en-us/library/jj679962(v=vs.113).aspx#Anchor_1 Assert.Equal("ID", EFSorting.FindSortableMember(typeof(TestClass_CodeFirstConv1))); Assert.Equal("TestClass_CodeFirstConv2Id", EFSorting.FindSortableMember(typeof(TestClass_CodeFirstConv2))); Assert.Null(EFSorting.FindSortableMember(typeof(TestClass_CodeFirstConv_InvalidType))); }
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.Skip > 0 || Options.Take > 0) && Compat.IsEntityFramework(Source.Provider)) Options.DefaultSort = EFSorting.FindSortableMember(typeof(S)); var deferPaging = Options.HasGroups || !CanUseRemoteGrouping && !SummaryIsTotalCountOnly && Options.HasSummary; var loadExpr = Builder.BuildLoadExpr(Source.Expression, !deferPaging); if(Options.HasAnySelect) { ContinueWithGrouping( ExecWithSelect(loadExpr).Select(ProjectionToDict), Accessors.Dict, result ); } else { ContinueWithGrouping( ExecExpr<S>(Source, loadExpr), new DefaultAccessor<S>(), result ); } if(deferPaging) result.data = Paginate(result.data, Options.Skip, Options.Take); if(ShouldEmptyGroups) EmptyGroups(result.data, Options.Group.Length); } return result; }
public static object Load <T>(IQueryable <T> source, DataSourceLoadOptionsBase options) { var isLinqToObjects = source is EnumerableQuery; var builder = new DataSourceExpressionBuilder <T>(options, isLinqToObjects); if (options.IsCountQuery) { return(builder.BuildCountExpr().Compile()(source)); } var accessor = new DefaultAccessor <T>(); var result = new DataSourceLoadResult(); var emptyGroups = options.HasGroups && !options.Group.Last().GetIsExpanded(); var canUseRemoteGrouping = options.RemoteGrouping.HasValue ? options.RemoteGrouping.Value : !isLinqToObjects; if (canUseRemoteGrouping && emptyGroups) { var groupingResult = ExecRemoteGrouping(source, builder, options); 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(T)); } if (!options.HasPrimaryKey && (options.Skip > 0 || options.Take > 0) && Compat.IsEntityFramework(source.Provider)) { options.DefaultSort = EFSorting.FindSortableMember(typeof(T)); } var deferPaging = options.HasGroups || options.HasSummary && !canUseRemoteGrouping; var queryResult = ExecQuery(builder.BuildLoadExpr(!deferPaging).Compile(), source, options); IEnumerable data = queryResult; if (options.HasGroups) { data = new GroupHelper <T>(accessor).Group(queryResult, options.Group); if (options.RequireGroupCount) { result.groupCount = (data as IList).Count; } } if (canUseRemoteGrouping && options.HasSummary && !options.HasGroups) { var groupingResult = ExecRemoteGrouping(source, builder, options); result.totalCount = groupingResult.TotalCount; result.summary = groupingResult.Totals; } else { if (options.RequireTotalCount) { result.totalCount = builder.BuildCountExpr().Compile()(source); } if (options.HasSummary) { data = Buffer <T>(data); result.summary = new AggregateCalculator <T>(data, accessor, options.TotalSummary, options.GroupSummary).Run(); } } if (deferPaging) { data = Paginate(data, options.Skip, options.Take); } if (emptyGroups) { EmptyGroups(data, options.Group.Length); } result.data = data; } if (result.IsDataOnly()) { return(result.data); } 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); }