Пример #1
0
        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);
        }
Пример #4
0
        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);
        }