예제 #1
0
        private QueryableMethodsVisitor PreEvaluateExpressionAndGetQueryableMethodsVisitor(ref Expression expression)
        {
            // replacing Count(predicate) with Where(predicate).Count()
            expression = ScalarMethodsVisitor.Visit(expression);

            // pre-executing everything, that can be executed locally
            expression = SubtreeEvaluator.Value.EvaluateSubtree(expression);

            // traversing the expression to find out the type of entities to be returned
            var entityTypeExtractor = new EntityTypeExtractionVisitor();

            entityTypeExtractor.Visit(expression);

            if (entityTypeExtractor.TableEntityType == null)
            {
                throw new InvalidOperationException("Failed to extract the table entity type from the query");
            }

            var entityType = entityTypeExtractor.EntityType ?? entityTypeExtractor.TableEntityType;

            // translating the query into set of conditions and converting the expression at the same time
            // (all Queryable method calls will be replaced by a param of IQueryable<T> type)
            var visitor = new QueryableMethodsVisitor(entityType, entityTypeExtractor.TableEntityType);

            expression = visitor.Visit(expression);

            visitor.TranslationResult.CustomizationHooks = this.CustomizationHooks;

            return(visitor);
        }
예제 #2
0
        /// <summary>
        /// Evaluates LINQ expression and queries DynamoDb table for results
        /// </summary>
        internal object ExecuteQuery(Expression expression)
        {
            // replacing Count(predicate) with Where(predicate).Count()
            expression = ScalarMethodsVisitor.Visit(expression);

            // pre-executing everything, that can be executed locally
            expression = SubtreeEvaluator.Value.EvaluateSubtree(expression);

            // traversing the expression to find out the type of entities to be returned
            var entityTypeExtractor = new EntityTypeExtractionVisitor();

            entityTypeExtractor.Visit(expression);

            if (entityTypeExtractor.TableEntityType == null)
            {
                throw new InvalidOperationException("Failed to extract the table entity type from the query");
            }

            Type entityType = entityTypeExtractor.EntityType ?? entityTypeExtractor.TableEntityType;

            // translating the query into set of conditions and converting the expression at the same time
            // (all Queryable method calls will be replaced by a param of IQueryable<T> type)
            var visitor = new QueryableMethodsVisitor(entityType, entityTypeExtractor.TableEntityType);

            expression = visitor.Visit(expression);

            // executing get/query/scan operation against DynamoDb table
            var result = this._tableWrapper.LoadEntities(visitor.TranslationResult, entityType);

            // trying to support other (mostly Enumerable's single-entity) operations
            var enumerableResult = result as IEnumerable;

            if (enumerableResult != null)
            {
                var queryableResult = enumerableResult.AsQueryable();

                var lambda = Expression.Lambda(expression, visitor.EnumerableParameterExp);

                // Here the default methods for IEnumerable<T> are called.
                // This allows to support First(), Last(), Any() etc.
                try
                {
                    result = lambda.Compile().DynamicInvoke(queryableResult);
                }
                catch (TargetInvocationException ex)
                {
                    throw ex.InnerException;
                }
            }
            return(result);
        }