private Expression TranslateInternal(Expression expression, TranslateOptions options)
        {
            var syntax      = TranslateScope.Current.Context.Database.Provider.GetService <ISyntaxProvider>();
            var translation = QueryBinder.Bind(expression, syntax);

            translation = LogicalDeleteFlagRewriter.Rewrite(translation);
            translation = GlobalQueryPolicyRewriter.Rewrite(translation);
            translation = AggregateRewriter.Rewrite(translation);
            translation = UnusedColumnRemover.Remove(translation);
            translation = RedundantColumnRemover.Remove(translation);
            translation = RedundantSubqueryRemover.Remove(translation);
            translation = RedundantJoinRemover.Remove(translation);

            var bound = RelationshipBinder.Bind(translation);

            if (bound != translation)
            {
                translation = bound;
                translation = RedundantColumnRemover.Remove(translation);
                translation = RedundantJoinRemover.Remove(translation);
            }
            translation = ComparisonRewriter.Rewrite(translation);

            var rewritten = RelationshipIncluder.Include(TranslateScope.Current.Context, translation);

            if (rewritten != translation)
            {
                translation = rewritten;
                translation = UnusedColumnRemover.Remove(translation);
                translation = RedundantColumnRemover.Remove(translation);
                translation = RedundantSubqueryRemover.Remove(translation);
                translation = RedundantJoinRemover.Remove(translation);
            }

            rewritten = SingletonProjectionRewriter.Rewrite(translation);
            if (rewritten != translation)
            {
                translation = rewritten;
                translation = UnusedColumnRemover.Remove(translation);
                translation = RedundantColumnRemover.Remove(translation);
                translation = RedundantSubqueryRemover.Remove(translation);
                translation = RedundantJoinRemover.Remove(translation);
            }

            rewritten = ClientJoinedProjectionRewriter.Rewrite(translation);
            if (rewritten != translation)
            {
                translation = rewritten;
                translation = UnusedColumnRemover.Remove(translation);
                translation = RedundantColumnRemover.Remove(translation);
                translation = RedundantSubqueryRemover.Remove(translation);
                translation = RedundantJoinRemover.Remove(translation);
            }

            translation = BuildExpression(translation);

            return(translation);
        }
        protected virtual Expression BuildExpression(Expression expression)
        {
            expression = UnusedColumnRemover.Remove(expression);
            expression = RedundantColumnRemover.Remove(expression);
            expression = RedundantSubqueryRemover.Remove(expression);

            var rewritten = CrossApplyRewriter.Rewrite(expression);

            rewritten = CrossJoinRewriter.Rewrite(rewritten);

            if (rewritten != expression)
            {
                expression = rewritten;
                expression = UnusedColumnRemover.Remove(expression);
                expression = RedundantSubqueryRemover.Remove(expression);
                expression = RedundantJoinRemover.Remove(expression);
                expression = RedundantColumnRemover.Remove(expression);
            }

            return(expression);
        }
        private Expression TranslateInternal(TranslateContext transContext, Expression expression)
        {
            var translation = QueryBinder.Bind(transContext, expression);

            translation = LogicalDeleteFlagRewriter.Rewrite(translation);
            translation = GlobalQueryPolicyRewriter.Rewrite(translation);
            translation = AggregateRewriter.Rewrite(translation);
            translation = UnusedColumnRemover.Remove(translation);
            translation = RedundantColumnRemover.Remove(translation);
            translation = RedundantSubqueryRemover.Remove(translation);
            translation = RedundantJoinRemover.Remove(translation);

            var bound = RelationshipBinder.Bind(transContext, translation);

            if (bound != translation)
            {
                translation = bound;
                translation = RedundantColumnRemover.Remove(translation);
                translation = RedundantJoinRemover.Remove(translation);
            }

            translation = ComparisonRewriter.Rewrite(translation);

            Expression rewritten;

            if (transContext.QueryPolicy != null)
            {
                rewritten = RelationshipIncluder.Include(transContext, translation);
                if (rewritten != translation)
                {
                    translation = rewritten;
                    translation = UnusedColumnRemover.Remove(translation);
                    translation = RedundantColumnRemover.Remove(translation);
                    translation = RedundantSubqueryRemover.Remove(translation);
                    translation = RedundantJoinRemover.Remove(translation);
                }
            }

            rewritten = SingletonProjectionRewriter.Rewrite(translation);
            if (rewritten != translation)
            {
                translation = rewritten;
                translation = UnusedColumnRemover.Remove(translation);
                translation = RedundantColumnRemover.Remove(translation);
                translation = RedundantSubqueryRemover.Remove(translation);
                translation = RedundantJoinRemover.Remove(translation);
            }

            rewritten = ClientJoinedProjectionRewriter.Rewrite(translation);
            if (rewritten != translation)
            {
                translation = rewritten;
                translation = UnusedColumnRemover.Remove(translation);
                translation = RedundantColumnRemover.Remove(translation);
                translation = RedundantSubqueryRemover.Remove(translation);
                translation = RedundantJoinRemover.Remove(translation);
            }

            translation = BuildExpression(translation);

            return(translation);
        }