Exemplo n.º 1
0
        /// <summary>
        /// Combine multiple expressions using Or.  Any null expressions are skipped.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expressions"></param>
        /// <returns></returns>
        public static Expression <Func <T, bool> > CombineOr <T>(params Expression <Func <T, bool> >[] expressions)
        {
            Expression <Func <T, bool> > ret = null;

            foreach (var expression in expressions)
            {
                if (expression == null)
                {
                    continue;
                }

                if (ret == null)
                {
                    ret = expression;
                }
                else
                {
                    ret = WhereExpressionUtilities.Or(ret, expression);
                }
            }
            return(ret);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Function that actually executes as the data loader.
        /// </summary>
        /// <typeparam name="Model"></typeparam>
        /// <param name="requests"></param>
        /// <returns></returns>
        protected virtual async Task <Dictionary <DataLoaderRequest <Model, PrimaryKey>, IEnumerable <Model> > > LoadData <Model, PrimaryKey>(IEnumerable <DataLoaderRequest <Model, PrimaryKey> > requests)
            where Model : class
        {
            using var scope = _serviceProvider.CreateScope(); var repository = scope.ServiceProvider.GetService <IRepository <Model, PrimaryKey> >();

            // If we only have one request to handle, we can do everyting on the server without any fancy processing, so handle that case now.
            // (Unless we are using a feature not supported by the repository API (e.g. ThenBy), in which case we still treat it as a batch).
            if (requests.Count() == 1)
            {
                var request = requests.First();

                bool needCodeSideOrdering = request.ThenBy != null ||
                                            request.OrderByDescending;

                if (!needCodeSideOrdering)
                {
                    var singleResults = await repository.FindAllAsync(request.Where, request.OrderBy, request.Skip, request.Take);

                    return(requests.ToDictionary(
                               item => item,
                               item => singleResults
                               ));
                }
                else
                {
                    var singleResults = await repository.FindAllAsync(request.Where, request.OrderBy);

                    var batchResult = singleResults;
                    if (request.OrderBy != null)
                    {
                        IOrderedEnumerable <Model> ordered;

                        if (request.OrderByDescending)
                        {
                            ordered = batchResult
                                      .OrderByDescending(request.OrderBy.Compile());
                        }
                        else
                        {
                            ordered = batchResult
                                      .OrderBy(request.OrderBy.Compile());
                        }

                        if (request.ThenBy != null)
                        {
                            if (request.ThenByDescending)
                            {
                                ordered = ordered
                                          .ThenByDescending(request.ThenBy.Compile());
                            }
                            else
                            {
                                ordered = ordered
                                          .ThenBy(request.ThenBy.Compile());
                            }
                        }

                        batchResult = ordered;
                    }

                    if (request.Skip != 0)
                    {
                        batchResult = batchResult.Skip(request.Skip);
                    }

                    if (request.Take.HasValue)
                    {
                        batchResult = batchResult.Take(request.Take.Value);
                    }

                    return(requests.ToDictionary(
                               item => item,
                               item => batchResult
                               ));
                }
            }

            // Otherwise we need to read everything we require and then apply the order, skip, and take after getting the data.
            //


            // Build a combined where clause.
            Expression <Func <Model, bool> > whereAny = null;

            foreach (var request in requests)
            {
                if (whereAny == null)
                {
                    whereAny = request.Where;
                }
                else
                {
                    whereAny = WhereExpressionUtilities.Or(whereAny, request.Where);
                }
            }

            // Read all results for all batched requests.
            var results = await repository.FindAllAsync(whereAny);


            // Split the results back out by their requests, applying the order, skip, and take.
            var ret = requests.ToDictionary(
                item => item,
                item =>
            {
                var batchResult = results.Where(item.Where.Compile());
                if (item.OrderBy != null)
                {
                    IOrderedEnumerable <Model> ordered;

                    if (item.OrderByDescending)
                    {
                        ordered = batchResult
                                  .OrderByDescending(item.OrderBy.Compile());
                    }
                    else
                    {
                        ordered = batchResult
                                  .OrderBy(item.OrderBy.Compile());
                    }

                    if (item.ThenBy != null)
                    {
                        if (item.ThenByDescending)
                        {
                            ordered = ordered
                                      .ThenByDescending(item.ThenBy.Compile());
                        }
                        else
                        {
                            ordered = ordered
                                      .ThenBy(item.ThenBy.Compile());
                        }
                    }

                    batchResult = ordered;
                }

                if (item.Skip != 0)
                {
                    batchResult = batchResult.Skip(item.Skip);
                }

                if (item.Take.HasValue)
                {
                    batchResult = batchResult.Take(item.Take.Value);
                }

                return(batchResult);
            }
                );

            return(ret);
        }